HTTP请求中的form data和request payload的区别

来源:互联网 发布:h2o 数据挖掘 编辑:程序博客网 时间:2024/05/22 13:42

jQuery的ajax方法和post方法分别发送请求,在后台Servlet进行处理时结果是不一样的,比如用$.ajax方法发送请求时(data参数是一个JSON.stringify()处理后的字符串,而不是一个JSON对象),servlet里可以这样使用Gson来解析:

new Jsonparser().parse(request.getReader())

但此时是不可用request.getParam(key) 来取值的。

如果用$.post方法来发送请求(data参数是一个JSON对象,而不要再用JSON.stringify()处理为字符串了),结果恰恰相反。

在Chrome中调试发现,$.ajax发送的请求显示在request payload下面,而使用$.post方法发送的请求显示在form data下面。有什么区别呢?

关键就是设置Content-type这个Header为application/x-www-form-urlencoded,实际上对于常规的HTML页面上的form的Content-type默认就是这个值。

这里要注意post请求的Content-Type为application/x-www-form-urlencoded,参数是在请求体中,即上面请求中的Form Data。

在servlet中,可以通过request.getParameter(name)的形式来获取表单参数。

 而如果使用原生AJAX POST请求的话:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function getXMLHttpRequest() { 
          var xhr; 
          if(window.ActiveXObject) { 
                   xhr= new ActiveXObject("Microsoft.XMLHTTP"); 
          }else if (window.XMLHttpRequest) { 
                   xhr= new XMLHttpRequest(); 
          }else 
                   xhr= null
          
          return xhr; 
   
function save() { 
          var xhr = getXMLHttpRequest(); 
          xhr.open("post","http://127.0.0.1:8080/test/test.do"); 
          var data = "name=mikan&address=street..."
          xhr.send(data); 
          xhr.onreadystatechange= function() { 
                   if(xhr.readyState == 4 && xhr.status == 200) { 
                            alert("returned:"+ xhr.responseText); 
                   
          }; 

  通过chrome的开发者工具看到请求头如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
RequestURL:http://127.0.0.1:8080/test/test.do 
Request Method:POST 
Status Code:200 OK 
    
Request Headers 
Accept:*/* 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6 
AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.2 
Connection:keep-alive 
Content-Length:28 
Content-Type:text/plain;charset=UTF-8 
Cookie:JSESSIONID=C40C7823648E952E7C6F7D2E687A0A89 
Host:127.0.0.1:8080 
Origin:http://127.0.0.1:8080 
Referer:http://127.0.0.1:8080/test/index.jsp 
User-Agent:Mozilla/5.0 (Windows NT 6.1)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.149 Safari/537.36 
    
Request Payload 
name=mikan&address=street 
    
Response Headers 
Content-Length:2 
Date:Sun, 11 May 2014 11:49:23 GMT 
Server:Apache-Coyote/1.1 

  注意请求的Content-Type为text/plain;charset=UTF-8,而请求表单参数在RequestPayload中。

那么servlet中通过request.getParameter(name)却是空。为什么呢?而这样的参数又该怎么样获取呢?

为了搞明白这个问题,查了些资料,也看了Tomcat7.0.53关于请求参数处理的源码,终于搞明白了是怎么回事。

HTTP POST表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,而使用原生AJAX的POST请求如果不指定请求头RequestHeader,默认使用的Content-Type是text/plain;charset=UTF-8。

 由于Tomcat对于Content-Type multipart/form-data(文件上传)和application/x-www-form-urlencoded(POST请求)做了“特殊处理”。下面来看看相关的处理代码。

Tomcat的HttpServletRequest类的实现类为org.apache.catalina.connector.Request(实际上是org.apache.coyote.Request),而它对处理请求参数的方法为protected void parseParameters(),这个方法中对Content-Type multipart/form-data(文件上传)和application/x-www-form-urlencoded(POST请求)的处理代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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; 
    

  从上面代码可以看出,Content-Type不是application/x-www-form-urlencoded的POST请求是不会读取请求体数据和进行相应的参数处理的,即不会解析表单数据来放到request parameter map中。所以通过request.getParameter(name)是获取不到的。

 那么这样提交的参数我们该怎么获取呢?

当然是使用最原始的方式,读取输入流来获取了,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
privateString getRequestPayload(HttpServletRequest req) { 
          StringBuildersb = new StringBuilder(); 
          try(BufferedReaderreader = req.getReader();) { 
                   char[]buff = new char[1024]; 
                   intlen; 
                   while((len = reader.read(buff)) != -1) { 
                            sb.append(buff,0, len); 
                   
          }catch (IOException e) { 
                   e.printStackTrace(); 
          
          returnsb.toString(); 

  

当然,设置了application/x-www-form-urlencoded的POST请求也可以通过这种方式来获取。

 所以,在使用原生AJAX POST请求时,需要明确设置Request Header,即:

 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 扫码注册显示手机号被占用怎么办 vivo手机屏锁密码忘了怎么办 手机号注册微博手机号不用了怎么办 微博更换手机号被别人注册过怎么办 怎么有个qq注册验证码怎么办 12306手机丢了密码忘了怎么办 教师考试注册时邮箱填写错误怎么办 计算机二级注册时邮箱填错了怎么办 注册时执业范围填错了怎么办 百度号被盗了申诉不回来怎么办 斗鱼直播伴侣显示分类不可用怎么办 斗鱼黑名单显示网络加载失败怎么办 平台登录验证码只能显示一半怎么办 想改微博密码但是忘了原密码怎么办 微博账号密码都忘了怎么办 新浪博客忘记邮箱和密码忘了怎么办 新浪助学贷款邮箱密码忘了怎么办 客厅的父母乐忘记密码了怎么办 微博密码忘记了手机号也换了怎么办 想改密码旧密码忘了怎么办 商标转让转让方不配合做补证怎么办 肇事后责任方拒赔怎么办久草www 我出车祸了对方逃逸找不到人怎么办 肇事车辆怀疑是故意伤人怎么办啊 法院判的交通事故罚金没钱交怎么办 公安抓人应该行政拘留却放了怎么办 停车场把人家车刮了跑了后怕怎么办 膝盖半月板损伤可走路不疼怎么办 面试过程中遇到写的笔没水怎么办 当学生会主席底下的人不服怎么办 中班学生放学总是不写作业怎么办 妻子不想离婚主动同认婚外情怎么办 淘宝自动退款超时了卖家怎么办 征途盟战刺探自己盟的没做怎么办 被蜜蜂蛰了但一周后奇痒怎么办 热带鱼小鱼抢食大鱼吃不到怎么办 家里养的植物土壤里有虫子怎么办 哺乳期乳房有硬块乳头有白点怎么办 税务查税拿到不开票销售合同怎么办 买地皮是集体证已交钱了怎么办 word里的字体都是英文版怎么办