对于JQueryAjax再封装使用及客户端传输参数问题解释
$(function(){
var base = $('#base').val();
var send = function(a, url, v, s, e) {
$.ajax({
async : a,
url : base + '/' + url,
contentType : "application/x-www-form-urlencoded; charset=utf-8",
data : v,
dataType : 'json',
type : 'post',
success : function(d) {
s(d);
},
error : function(d) {
e(d);
}
});
};
var sendJson = function(a, url, v, s, e) {
$.ajax({
async : a,
url : base + '/' + url,
contentType : "application/json; charset=utf-8",
data : JSON.stringify(v),
dataType : 'json',
type : 'post',
success : function(d) {
s(d);
},
error : function(d) {
e(d);
}
});
};
//其中第二个是用来发送json数组对象的正常情况下AJax发送post数据个contentType的值是application/x-www-form-urlencoded
//在使用此方法时springMVC用@requestbody注解指定HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。
在这里说明一下如果我们后台使用了原生的servlet实现的话对于Post请求参数获取都是依赖于tomcat来完成的,而tomcat在解析请求时只会对Content-Type multipart/form-data(文件上传)和application/x-www-form-urlencoded(POST请求)做特殊处理:因为表单提交数据是名值对的方式,且Content-Type为application/x-www-form-urlencoded,而文件上传服务器需要特殊处理,普通的post请求(Content-Type不是application/x-www-form-urlencoded)数据格式不固定,不一定是名值对的方式,所以服务器无法知道具体的处理方式,所以只能通过获取原始数据流的方式来进行解析。
从tomcat代码中我们可以看到其对requset响应的处理
protectedvoid parseParameters() {
//省略部分代码......
parameters.handleQueryParameters();// 这里是处理url中的参数
//省略部分代码......
if ("multipart/form-data".equals(contentType)) { // 这里是处理文件上传请求
parseParts();
success = true;
return;
}
if(!("application/x-www-form-urlencoded".equals(contentType))) {// 这里如果是非POST请求直接返回,不再进行处理
success = true;
return;
}
//下面的代码才是处理POST请求参数
//省略部分代码......
try {
if (readPostBody(formData, len)!= len) { // 读取请求体数据
return;
}
} catch (IOException e) {
// Client disconnect
if(context.getLogger().isDebugEnabled()) {
context.getLogger().debug(
sm.getString("coyoteRequest.parseParameters"),e);
}
return;
}
parameters.processParameters(formData, 0, len); // 处理POST请求参数,把它放到requestparameter map中(即request.getParameterMap获取到的Map,request.getParameter(name)也是从这个Map中获取的)
// 省略部分代码......
}
protected int readPostBody(byte body[], int len)
throws IOException {
int offset = 0;
do {
int inputLen = getStream().read(body, offset, len - offset);
if (inputLen <= 0) {
return offset;
}
offset += inputLen;
} while ((len - offset) > 0);
return len;
}
这也是为什么JS原生ajax函数如果不声明Content-type:
application/x-www-form-urlencoded servlet不能通过request.getParamter(name)获取参数值的原因。
当然,在我们开发中如果使用了web框架的话,框架会对响应的参数类型提供解析,如springMVC中参数前加上requestBody注解可以使用这个功能。