最近用http+post方式实现了系统间数据交互的需求.
常用的方式是 application/json方式直接post json对象 . 告诉服务器数据格式将会是
{ Name : 'John Smith', Age: 23}
如
{"siteId":"ZHAN20160329TDLXJND144649","apiSecret":"userid123","workNumber":"FJ-8006-160912-1715-00001","fluetype":"2","apiKey":"yyxt"}
后台可以直接springmvc直接接收并转为相关vo对象处理.
而在手机与后台交互的场景中遇到一种格式要求
方法名称:appScanBuildingData
请求:json字符串形式,最外层用data包裹
demo格式范例是
data={"alarmDetail":[{"address":"中国","cgi":"CGI0"},{"address":"米国","cgi":"CGI1"},{"address":"日本","cgi":"CGI2"}],"areaCode":"350723","cellNumber":"1599999","cityCode":"350723","lat":"232.545","lon":"98.233","workNO":"ZB33000333337"}
这两种数据需要有什么区别?
原因在于Content-Type 中application/x-www-form-urlencoded 和application/json的设置问题, 他们所代表传输的数据格式不同.
这种格式要求其实使用的Content-Type: 应该为application/x-www-form-urlencoded;
即提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码.
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
所以注意, 协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。下面就正式开始介绍它们。(application/json , application/x-www-form-urlencoded, 等等)
- 当以application/json的content-type传送数据,被传送的对象只需被json序列化。
消息主体中的格式
{ Name : 'John Smith', Age: 23}
- 当以application/x-www-form-urlencoded的方式传送数据。请求的内容需要以..=..&..=..的格式提交,在请求体内内容将会以”&”和“ = ”进行拆分。
消息主体中的格式
Name=John+Smith&Age=23
- application/json请求时,Springmvc可以直接处理转换为对象.
- application/x-www-form-urlencoded方式传输,后台接收时候可以采用
String data = request.getParameter("data"); 这样的方式来接受json格式的数据.
然后在转为Object使用:
AlarmInfo vo=null;
vo=JSONObject.parseObject(data, AlarmInfo.class);
约定这种格式的初衷估计就是后台为接收数据方便的考虑.
综上
data={"alarmDetail":[{"address":"中国","cgi":"CGI0"},{"address":"米国","cgi":"CGI1"},{"address":"日本","cgi":"CGI2"}],"areaCode":"350723","cellNumber":"1599999","cityCode":"350723","lat":"232.545","lon":"98.233","workNO":"ZB33000333337"}
其实和data=John 没本质区别.不过一个值是john的字符串.一个值是json对象数组格式的字符串. fuck.
此外梳理一下js的post请求
以下针对请求端进行一下说明, jsp中Jquery的提交为例: (参考https://segmentfault.com/a/1190000004982390)
$.ajax常见的格式:
$.ajax({
url: "mydomain.com/url",
type: "POST",
dataType: "xml/html/script/json", // expected format for response
contentType: "application/json", // send as JSON
data: $.param( $("Element or Expression") ), //或者采取其他$()的方法处理数据(serializearray())
- complete: function() {
//called when complete
},
success: function() {
//called when successful
},
error: function() {
//called when there is an error
},
});
jQuery中默认的表单提交方式为application/x-www-form-urlencoded,与XMLHttpRequest不同的地方在于:数据的URL方式编码,由jQuery来做,只需要在
$.ajax({})
参数中设置processData = true
(这也是默认,可省略)。
/* dataToSend为Object类型的表单数据,否则jQuery会抛出异常 */
$.ajax({
method: 'POST',
url: '...',
data: dataToSend,
contentType: 'application/x-www-form-urlencoded', // 可省略
processData: true, // 可省略
success: function() {...}
});
注意:若采用GET方式,则将method改为GET即可,不需要在url后面加上数据。
比如: 例子来源http://hayageek.com/jquery-ajax-form-submit/
html
<form name="ajaxform" id="ajaxform" action="ajax-form-submit.php" method="POST">
First Name: <input type="text" name="fname" value =""/> <br/>
Last Name: <input type="text" name="lname" value ="" /> <br/>
Email : <input type="text" name="email" value=""/> <br/>
</form>
js
$("#ajaxform").submit(function(e)
{
var postData = $(this).serializeArray();
var formURL = $(this).attr("action");
$.ajax(
{
url : formURL,
type: "POST",
data : postData,
contentType: 'application/json',
success:function(data, textStatus, jqXHR)
{
},
error: function(jqXHR, textStatus, errorThrown)
{
}
});
e.preventDefault(); //STOP default action
});
$("#ajaxform").submit(); //SUBMIT FORM
提交的数据
{"fname":"Ravi","lname":"Shanker","email":"xx@xxx.com"}
----------------------
备注:
- $(selector).serialize() 序列表表格内容为字符串,用于 Ajax 请求。可以对整个form,也可以只针对某部分。
$('#form').submit(function(event){
event.preventDefault();
$.ajax({
url:' ',
type:'post',
data:$("form").serialize(),
}
- $(selector).serializeArray()
serializeArray() 方法序列化表单元素(类似 .serialize() 方法),返回 JSON 数据结构数据。
注意:此方法返回的是 JSON 对象而非 JSON 字符串。需要使用插件或者第三方库进行字符串化操作。
返回的 JSON 对象是由一个对象数组组成的,其中每个对象包含一个或两个名值对 —— name 参数和 value 参数(如果 value 不为空的话)。举例来说:
[
{name: 'firstname', value: 'Hello'},
{name: 'lastname', value: 'World'},
{name: 'alias'}, // 值为空
]
.serializeArray() 方法使用了 W3C 关于 successful controls(有效控件) 的标准来检测哪些元素应当包括在内。特别说明,元素不能被禁用(禁用的元素不会被包括在内),并且元素应当有含有 name 属性。提交按钮的值也不会被序列化。文件选择元素的数据也不会被序列化。
该方法可以对已选择单独表单元素的对象进行操作,比如 <input>, <textarea>, 和 <select>。不过,更方便的方法是,直接选择 <form> 标签自身来进行序列化操作。
$("form").submit(function() {
console.log($(this).serializeArray());
return false;
});
上面的代码产生下面的数据结构(假设浏览器支持 console.log):
[
{
name: a
value: 1
},
{
name: b
value: 2
},
{
name: c
value: 3
},
{
name: d
value: 4
},
{
name: e
value: 5
}
]
- $.params() $.param()方法是serialize()方法的核心,用来对一个数组或对象按照key/value进行序列化。
序列化一个 key/value 对象:
var params = { width:1900, height:1200 };
var str = jQuery.param(params);
$("#results").text(str);结果:
width=1680&height=1050单个对象可以才用JSON.parse()和JSON.stringify()处理1.parse 用于从一个字符串中解析出json 对象。例如
var str='{"name":"cpf","age":"23"}'
经 JSON.parse(str) 得到:
Object: age:"23"
name:"cpf"
_proto_:Object
ps:单引号写在{}外,每个属性都必须双引号,否则会抛出异常 2.stringify用于从一个对象解析出字符串,例如
var a={a:1,b:2}
经 JSON.stringify(a)得到:
“{“a”:1,"b":2}”