http form 请求参数form表单序列化化

http://blog.csdn.net/yy/article/details/
http://blog.johnsonlu.org/angularjs-ajax/
问题现象:$http发送post请求,后台获取不到前端提交的数据。
由於 AngularJS 的 POST 預設用的 Content-Type 是 application/charset=utf-8,而且也不會對資料做serialize的處理,如果直接使用後端會抓不到 POST 的資料
解决办法1 —— 使用jquery:
解决办法2 —— 自己序列化:
var app = angular.module("sqhApp",["ionic"], function($httpProvider) {
// Use x-www-form-urlencoded Content-Type
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-charset=utf-8';
* T converts an object to x-www-form-urlencoded serialization.
* @param {Object} obj
* @return {String}
var param = function(obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj,
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
for(i=0; i&value. ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subV
query += param(innerObj) + '&';
else if(value instanceof Object) {
for(subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subV
query += param(innerObj) + '&';
else if(value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
return query.length ? query.substr(0, query.length - 1) :
// Override $http service's default transformRequest
$httpProvider.defaults.transformRequest = [function(data) {
return angular.isObject(data) && String(data) !== '[object File]' ? param(data) :
------------------------------------------------其他知识点--------------------------------------------------------
$http 发送请求的模板
method: string,
url: string,
params: object,
data: string or object,
headers: object,
transformRequest: function transform(data, headersGetter) or an array of functions,
transformResponse: function transform(data, headersGetter) or an array of functions,
cache: boolean or Cache object,
timeout: number,
withCredentials: boolean
示例(发送headers请求):
$http.get('api/user', {
//设置Authorization(授权)头。在真实的应用中,你需要到一个服务里面去获取auth令牌
headers: {'Authorization': 'Basic Qzsda231231'},
params: {id:5}
}).success(function() {//处理成功的情况 });
angularjs $http事务实现form表单序列化提交
angularJs中$scope数据序列化
没有更多推荐了,springboot学习(三)——http序列化/反序列化之HttpMessageConverter
时间: 18:59:20
&&&& 阅读:158
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&以下内容,如有问题,烦请指出,谢谢!
上一篇说掉了点内容,这里补上,那就是springmvc的http的序列化/反序列化,这里简单说下如何在springboot中使用这个功能。
使用过原生netty http的人可能对http序列化比较熟悉,springmvc中的意思跟netty中的意思一样。http序列化(或者叫作http报文编码),就是将Java类转化为二进制流输出给http body;http反序列化,就是将http报文转换为程序内部的Java类。有了http反序列化,就不用再去一个个request.getParam("xxx")来获取参数,有了http序列化,就不用直接通过response.getWriter.write来输出结果。后面为了简单,http序列化/反序列化统一称作http序列化。
http序列化是一个合格的controller框架都应该具备的功能,有了它,在很多场景下,controller的方法只用写调用service的那一行代码,大大简化了业务代码逻辑的复杂性。
在springmvc中可以在controller方法的代码中直接写Java类作为参数,这样默认是通过参数名和属性名的配对,使用request.getParam("xxx")来完成的。在前后端分离时,有时候需要处理一些很层次很深、很复杂的参数,这时候通过普通的form-data并不是一个很好的选择,它们可读性差,难以解析。这种场景直接使用一些文本型格式(json/xml)的序列化/反序列化是个比较好的选择,编码非常简单,也便于统一入口处理。在springmvc中简单的说就是通过@RequestBody和@ResponseBody来注解请求参数和返回值,这个相信使用过springmvc的都知道怎么用。
那么不使用json格式来传输数据行不行,当然可以,http虽然名字是叫文本,但是一样可以用来传输二进制数据,也就是所有格式的数据。这样看起来可能很奇怪,但是在一些与非web前端进行http通信的地方,自定义http的数据格式就很常见,比如基于http的rpc服务。rpc为了满足通用性、低消耗性,一般会选择跨语言、时间性能好、压缩比高的序列化格式,比如protobuf。
springmvc自己就提供了protobuf的http序列化,在spring-web包中有个类叫做org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter,就是用来处理protobuf格式的数据的,有兴趣可以去试试。
参考ProtobufHttpMessageConverter,我们可以写一个自己的http序列化,使用Java原生序列化读写对象,代码如下。
package pr.study.springboot.configure.mvc.
import java.io.ByteArrayInputS
import java.io.ByteArrayOutputS
import java.io.IOE
import java.io.ObjectInputS
import java.io.ObjectOutputS
import java.nio.charset.C
import java.util.Base64;
import org.slf4j.L
import org.slf4j.LoggerF
import org.springframework.http.HttpInputM
import org.springframework.http.HttpOutputM
import org.springframework.http.MediaT
import org.springframework.http.converter.AbstractHttpMessageC
import org.springframework.http.converter.HttpMessageNotReadableE
import org.springframework.http.converter.HttpMessageNotWritableE
import org.springframework.util.StreamU
import pr.study.springboot.bean.BaseB
public class JavaSerializationConverter extends AbstractHttpMessageConverter&Object& {
private Logger LOGGER = LoggerFactory.getLogger(JavaSerializationConverter.class);
public JavaSerializationConverter() {
// 构造方法中指明consumes(req)和produces(resp)的类型,指明这个类型才会使用这个converter
super(new MediaType("application", "x-java-serialization", Charset.forName("UTF-8")));
protected boolean supports(Class&?& clazz) {
return BaseBean.class.isAssignableFrom(clazz);
protected Object readInternal(Class&? extends Object& clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
byte[] bytes = StreamUtils.copyToByteArray(inputMessage.getBody());
// base64使得二进制数据可视化,便于测试
ByteArrayInputStream bytesInput = new ByteArrayInputStream(Base64.getDecoder().decode(bytes));
ObjectInputStream objectInput = new ObjectInputStream(bytesInput);
return objectInput.readObject();
} catch (ClassNotFoundException e) {
LOGGER.error("exception when java deserialize, the input is:{}", new String(bytes, "UTF-8"), e);
return null;
protected void writeInternal(Object t, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
ByteArrayOutputStream bytesOutput = new ByteArrayOutputStream();
ObjectOutputStream objectOutput = new ObjectOutputStream(bytesOutput);
objectOutput.writeObject(t);
// base64使得二进制数据可视化,便于测试
outputMessage.getBody().write(Base64.getEncoder().encode(bytesOutput.toByteArray()));
可以使用下面的代码来,配置这个converter
public void extendMessageConverters(List&HttpMessageConverter&?&& converters) {
// 仅仅添加一种新的converter,不删除默认添加的
// 如果要删除可以使用 converters.clear()
// 仅仅只有一种converter时,代表请求和响应默认都是这个converter代表的mediatype
// 推荐使用这个方法添加converter
converters.add(new JavaSerializationConverter());
// 添加converter的第二种方式,会删除原来的converter
public HttpMessageConverter&Object& javaSerializationConverter() {
return new JavaSerializationConverter();
// 添加converter的第三种方式,会删除原来的converter
public void configureMessageConverters(List&HttpMessageConverter&?&& converters) {
converters.add(new JavaSerializationConverter());
上面的代码要放在我们写的WebMvcConfigurerAdapter的子类中,如果使用我的代码,那就是在pr.study.springboot.configure.mvc.SpringMvcConfigure中。推荐使用第一种方式,如果你的业务确定只有一种http序列化方式,可以使用下面的几种,提升一些效率。
converter的代码里面注意一点,构造方法中千万要指明mediaType的类型(使用父类的构造方法是个很好的选择),指明这个类型才有机会使用这个converter。具体就是:
通过http请求中的Headers.Content-Type指定的mediaType来决定使用哪个converter(controller方法要支持consumes这种mediaType)来处理这个req的body的序列化;
通过http请求中的Headers.Accept指定的mediaType来决定使用哪个converter(controller方法要支持produces这种mediaType)来处理这个req的对应的resp的body的序列化,处理成功时对应的resp返回一个属于Accept子集的Content-Type;
json序列化使用下面的json
{"id":123,"name":"helloworld","email":"","createTime":" 15:22:55"}
java序列化使用下面的数据
rO0ABXNyAB1wci5zdHVkeS5zcHJpbmdib290LmJlYW4uVXNlcrt1879rvWjlAgAESgACaWRMAApjcmVhdGVUaW1ldAAQTGphdmEvdXRpbC9EYXRlO0wABWVtYWlsdAASTGphdmEvbGFuZy9TdHJpbmc7TAAEbmFtZXEAfgACeHIAIXByLnN0dWR5LnNwcmluZ2Jvb3QuYmVhbi5CYXNlQmVhbklx6Fsr8RKpAgAAeHAAAAAAAAAAe3NyAA5qYXZhLnV0aWwuRGF0ZWhqgQFLWXQZAwAAeHB3CAAAAWBjWqyYeHQAEGhlbGxvd29ybGRAZy5jb210AApoZWxsb3dvcmxk
用来测试的代码如下:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userS
@GetMapping("/{id}")
public User getUserById(@PathVariable long id) {
return userService.getUserById(id);
@PostMapping
public User createUser(@RequestBody User user) {
System.err.println("create an user: " + user);
public class UserServiceImpl implements UserService {
public User getUserById(long id) {
User user = new User();
user.setId(123L);
user.setName("helloworld");
user.setEmail("");
user.setCreateTime(new Date());
下面的是一些运行结果图,对比下可以看出Accept和Content-Type对序列化反序列化的影响。
GET + Accept: application/x-java-serialization,resp使用java序列化返回
GET + Accept: application/json,resp使用json序列化返回
POST + Content-Type: application/x-java-serialization + Accept: application/x-java-serialization,req和resp都使用java序列化
POST + Content-Type: application/x-java-serialization + Accept: application/json,req使用java序列化,resp使用json序列化
POST + Content-Type: application/json + Accept: application/json,req和resp都使用json序列化
POST + Content-Type: application/json + Accept: application/x-java-serialization,req使用json序列化,resp使用java序列化
这里为了测试,post返回的是User对象,直接返回基本类型(包装类/BigDecimal)以及String的话,不会走普通对象序列化,会处理成直接使用它们的通用格式返回。
实际中根据应用的req/resp应用场景,来决定controller方法的consumes和produces,忽略这两个属性通常情况下不会有问题,springmvc内部的mediaType匹配机制还是比较好的。
再说点其他的小内容。
springmvc默认使用的是jackson框架来处理json。jackson在实际使用中还需要进行一些配置,比如关闭null值的属性的序列化,以及时间的序列化格式等等。要配置jackson,只需要自己配置注入ObjectMapper即可。如下:
package pr.study.springboot.configure.mvc.
import java.text.SimpleDateF
import org.springframework.context.annotation.B
import org.springframework.context.annotation.C
import com.fasterxml.jackson.annotation.JsonInclude.I
import com.fasterxml.jackson.databind.ObjectM
* jackson的核心是ObjectMapper,在这里配置ObjectMapper来控制springboot使用的jackson的某些功能
@Configuration
public class MyObjectMpper {
public ObjectMapper getObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL); // 不序列化null的属性
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); // 默认的时间序列化格式
如果要使用fastJson怎么办(有些公司会要求这些基础组件都使用相同的jar包,便于扩展维护)?跟在springmvc中方式差不多,自己配置一个FastJsonHttpMessageConverter就行。在springboot中的配置方式和上面我们写的java序列化差不多,mvc配置类中添加下列代码即可:
public void extendMessageConverters(List&HttpMessageConverter&?&& converters) {
// 仅仅添加一种新的converter,不删除默认添加的
// 如果要删除可以使用 converters.clear()
// 仅仅只有一种converter时,代表请求和响应默认都是这个converter代表的mediatype
// 推荐使用这个方法添加converter
converters.add(new JavaSerializationConverter());
// 使用fastJson代替jackson
FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue); // 序列化null属性
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); // 默认的时间序列化格式
fastJsonConverter.setFastJsonConfig(fastJsonConfig);
converters.add(fastJsonConverter);
System.err.println(converters);
其他的再说一点,上面有说一个自定义JsonSerializer,这个有什么用呢?简单说就是你可以自己指定任何对象的json序列化格式,比如时间你可以序列化成中文的一些格式,rgb颜色一般都是三个byte存储,你可以序列化成css通用的格式。
这个功能我没用过,不过在网上找了个例子,大家可以参考下,说的是。
代码相关:
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://www.cnblogs.com/page12/p/8052758.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!表单序列化
随着Ajax的出现,表单序列化已经成为一种常见需求。在JS中,可以利用表单字段的type属性,连同name和value属性一起实现对表单的序列化。在编写代码前,先了解一下表单提交期间,浏览器是怎么样将数据发送给服务器的;
1.对表单字段的名称和值进行URL编码,使用和号(&)分割。
2.不发送禁用的表单字段
3.只发送勾选的复选框和单选按钮。
4.不发送type为"reset"和"button"的按钮。
5.多选选择框中的每个选中的值单独一个条目。
6.在单击提交按钮提交表单的情况下,也会发生提交按钮;否则,不发送提交按钮。也包括type为"image"的&input&元素。
7.&select&元素的值,就是选中的&option&元素的value特性的值。如果&option&元素没有value特性,则是&option&元素的文本值。
在表单序列化的过程中,一般不包含任何按钮字段,因为结果字符串可能是通过其他方式提交的。除此之外的其他上述规则都应该遵循,下面是表单序列化的代码。
&!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML =01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&
&title& New Document &/title&
&meta name="Generator" content="EditPlus"&
&meta name="Author" content=""&
&meta name="Keywords" content=""&
&meta name="Description" content=""&
&form id="form1"&
loginNo&input type="text" name="loginNo"&&/input&&br&
password&input type="password" name="password"&&/input&&br&
&button type="button" onclick="submitCk()"&submit&/button&
function submitCk(){
var form=document.getElementById("form1");
alert(serialize(form));
function serialize(form){
var parts=[],
field=null,
for(i=0,len=form.elements.i&i++){
field=form.elements[i];
switch(field.type){
case "select-one":
case "select-multiple":
if(field.name.length){
for(j=0,optLen=field.options.j&optLj++){
option=field.options[j];
if(option.selected){
optValue="";
if(option.hasAttribute){
optValue=(option.hasAttribute("value")?
option.value:option.text);
optValue=(option.attributes["value"].specified?
option.value:option.text);
parts.push(encodeURIComponent(field.name)+"="+
encodeURIComponent(optValue));
case undefined:
case "file":
//文件输入
case "submit": //提交按钮
case "reset": //重置按钮
case "button": //自定义按钮
case "radio":
//单选按钮
case "checkbox":
if(!field.checked){
/*执行默认操作*/
//不包含没有名字的表单字段
if(field.name.length){
parts.push(encodeURIComponent(field.name)+"="+
encodeURIComponent(field.value));
return parts.join("&");
上面这个serialize()函数首先定义了名为parts的数组,用于保存将要创建的字符串的各个部分。然后,通过for循环迭代每个表单字段,并将其保存在field变量中。在获得了一个字段的引用之后,使用switch语句检测其type属性。序列化过程中最麻烦的就是&select&元素,它可能是单选框也是多选框。因此需要遍历每一个选项,并在对应的数组中添加一个值。对于表单中的"file",“submit"等属性则不需要序列化。执行default的时候,即将当前字段的名称和值进行编码,然后添加到parts数组中,函数的最后一步是使用join格式化整个字符串;
get请求和post请求的区别?
from 表单序列化提交
METHOD的GET和POST属性的区别
form提交方式Get与Post详解
JSP中form表单method提交信息方式
没有更多推荐了,项目中竟然遇到了这样的问题,要求客户端请求的方式为:参数按照json序列化,然后使用post方式传递给服务器。第一次看到这个东东有点一头雾水,刚开始开发的时候全部使用的get请求方式,因为当时公司不考虑数据安全问题。后来使用了post方式,使用到了session。这下倒好接触了序列化json,然后post方式提交。
首先需要引用谷歌的gson.jar文件,这里面有一些序列化参数的方法,我用到的比较简单直接使用了tojson(类名字);
定义最外层的类PostArgs:
public class PostArgs {
public BaseRequest baseR
public String newsId;
}里面嵌套BaseRequest类,
public class BaseRequest {
public UserInfo userI
}接着是第三层UserInfo类:
public class UserInfo {
public String userId;
public String userN
}在主程序里测试为:
PostArgs postArgs = new PostArgs();
BaseRequest baseRequest = new BaseRequest();
UserInfo userInfo = new UserInfo();
userInfo.userId = "walker";
baseRequest.action = "getAction";
baseRequest.version = "1.1.1";
postArgs.baseRequest = baseR
postArgs.newsId = "1000.1";
baseRequest.userInfo = userI
Gson gson = new Gson();
System.out.println(gson.toJson(postArgs));输出结果为:
{"baseRequest":{"action":"getAction","userInfo":{"userId":"walker"},"version":"1.1.1"},"newsId":"1000.1"}这样就完成了json的序列化。接下来就是把序列化的数据以post的方式提交给服务器了。
* post请求,
public static String post(String httpUrl, String parMap,Context context)
System.out.println("post:"+httpUrl);
InputStream input =//输入流
InputStreamReader isr =
BufferedReader buffer =
StringBuffer sb =
String line =
AssetManager am =//资源文件的管理工具类
/*post向服务器请求数据*/
HttpPost request = new HttpPost(httpUrl);
StringEntity se = new StringEntity(jsonArgs);
request.setEntity(se);
HttpResponse response = new DefaultHttpClient().execute(request);
int code = response.getStatusLine().getStatusCode();
System.out.println("postCode= " + code);
// 若状态值为200,则ok
if (code == HttpStatus.SC_OK) {
//从服务器获得输入流
input = response.getEntity().getContent();
isr = new InputStreamReader(input);
buffer = new BufferedReader(isr,10*1024);
sb = new StringBuffer();
while ((line = buffer.readLine()) != null) {
sb.append(line);
} catch (Exception e) {
//其他异常同样读取assets目录中的"local_stream.xml"文件
System.out.println("HttpClient post 数据异常");
e.printStackTrace();
} finally {
if(buffer != null) {
buffer.close();
if(isr != null) {
isr.close();
if(input != null) {
input.close();
} catch (Exception e) {
System.out.println("PostData:"+sb.toString());
return sb.toString();
}关键语句就两行:
StringEntity se = new StringEntity(jsonArgs);
request.setEntity(se);new一个StringEntity,然后把这个当做request的参数设置进去就OK了。
现在客户端基本上返回值基本上也是json格式的值了,post之后返回的字段就可以使用反序列化的方式了。参考
在开发的应用程序的过程中,我相信json是使用最多的轻量级的数据交换格式,这里我就不介绍有关json的概念了。主要说明一下有关json反序列化的问题,一般情况下我们解析json都是下边这种方式:
resultString是json类型的字符串,当转化为JSONObject类之后,我们还需要一个一个的去解析数据,
你是不是会感觉到这样很麻烦呢,特别是对于用的比较多的值得时候。谷歌也发现了这个问题,他们开发出了一个json反序列化包。我们可以将返回的键值格式转化为类的格式,这个时候当我们再次使用的时候,就是类名.属性名就可以获取该变量的值了。我在这里摘取几行关键的代码,
就这样就可以实现json反序列化了,这是在handler里面进行处理的,一般情况下我们都是通过网络获取json格式的数据的。反序列化之后我们就可以在handler里面接受该类,然后就可以非常方便的使用变量值了。因为URL是公司的,所以我注释掉了,返回值的类型在源代码里我把打印出来信息放到了注释里,这次得到的编码格式不是UTF-8的,大家凑合着看吧。
handler里面处理数据代码
结果只是测试用的,所以直接使用了get(0)
这里也使用了handler机制,还有进度条的使用,如果有不懂得可以去论坛里找相关的教程和例子。CSDN上也有很多大牛的博客里也有提及。
HttpPost 传输Json数据并解析
Java序列化对象的一个使用案例-使用Http发送对象
[HTTP那些事]JSON反序列化
postman发送json格式的post请求
使用HttpClient和WebRequest时POST一个对象的写法
秒懂Java序列化与反序列化
调用webservice时提示对操作的回复消息正文进行反序列化时出错
几种常用序列化和反序列化方法
springMVC中restful利用@RequestBody注解进行json 与object的转换
没有更多推荐了,首先对某一表单进行Json对象序列化: 
[javascript]
var proRuestl_1 = $("#proResult1").serializeJson();//数据序列化
var proRuestl_2= $("#proResult2").serializeJson();//数据序列化
var proRuestl_3= $("#proResult3").serializeJson();//数据序列化
然后对数据的合拼
[javascript]
最后用ajax提交
[javascript]
这样不单可以提交多个表单的参数,还可以防止乱码的出现!
jquery批量获取form表单要提交的值
jquery批量提交表单值 和批量设置表单值
一个表单同时提交多条记录
form表单提交json格式数据
没有更多推荐了,

我要回帖

更多关于 form序列化 的文章

 

随机推荐