Ajax of Text/plain, application/x-www-form-urlencoded and Application/json
In the HTTP request, if it is a GET request, then the form parameter is appended to the URL in the form of name=value&name1=value1, and if it is a POST request, then the form parameter is in the request body, also in the name=value&name1= The form of value1 in the request body. The Chrome developer tool can be seen as follows (here is a readable form, not a request format for the real HTTP request protocol):
GET Request:
[plain] view plain copy
- Requesturl:http://127.0.0.1:8080/test/test.do?name=mikan&address=street
- Request Method:get
- Status code:200 OK
- Request Headers
- accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
- 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
- cookie:jsessionid=74ac93f9f572980b6fc10474cd8edd8d
- host: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
- Query String Parameters
- Name:mikan
- Address:street
- Response Headers
- Content-length:2
- Date:sun, 10:42:38 GMT
- server:apache-coyote/1.1
POST request:
[plain] view plain copy
- Requesturl:http://127.0.0.1:8080/test/test.do
- Request Method:post
- Status code:200 OK
- Request Headers
- accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
- 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
- Cache-control:max-age=0
- Connection:keep-alive
- Content-length:25
- content-type:application/x-www-form-urlencoded
- cookie:jsessionid=74ac93f9f572980b6fc10474cd8edd8d
- 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
- Form Data
- Name:mikan
- Address:street
- Response Headers
- Content-length:2
- Date:sun, 11:05:33 GMT
- server:apache-coyote/1.1
Note here that the content-type of the POST request is application/x-www-form-urlencoded, and the parameter is in the request body, which is the form Data in the request above.
In a servlet, form parameters can be obtained in the form of Request.getparameter (name).
And if you use the native Ajax POST request:
[JavaScript] view plain copy
- 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);
- }
- };
- }
The request header is shown by Chrome's developer tool as follows:
[plain] view plain copy
- 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:49:23 GMT
- server:apache-coyote/1.1
Note The requested Content-type is Text/plain;charset=utf-8, and the request form parameter is in Requestpayload.
Then the servlet passed Request.getparameter (name) is empty. Why is it? And how should such parameters be obtained?
In order to understand this problem, looked up some information, also read the Tomcat7.0.53 about the request parameter processing source code, finally figured out what is going on.
When an HTTP post form requests a commit, the content-type used is application/x-www-form-urlencoded, and the POST request that uses the native AJAX does not specify the request header Requestheader, The default content-type used is text/plain;charset=utf-8.
Because Tomcat has "special handling" for Content-type multipart/form-data (file upload) and application/x-www-form-urlencoded (POST request). Here's a look at the related processing code.
The implementation class for Tomcat's HttpServletRequest class is org.apache.catalina.connector.Request (actually org.apache.coyote.Request), and its method for processing request parameters is PROTECTE d void Parseparameters (), this method for Content-type multipart/form-data (file upload) and application/ The processing code for the x-www-form-urlencoded (POST request) is as follows:
[Java] view plain copy
- Protectedvoid Parseparameters () {
- Omit part of the code ...
- Parameters.handlequeryparameters ();//This is the processing of the parameters in the URL
- Omit part of the code ...
- if ("Multipart/form-data". Equals (ContentType)) {//Here is processing file upload request
- Parseparts ();
- Success = true;
- return;
- }
- if (! ("application/x-www-form-urlencoded". Equals (ContentType))) {//here if the non-POST request is returned directly, no longer processed
- Success = true;
- return;
- }
- The following code is the processing of the POST request parameters
- Omit part of the code ...
- Try {
- if (Readpostbody (FormData, len)! = len) {//Read request body Data
- return;
- }
- } catch (IOException e) {
- Client Disconnect
- if (Context.getlogger (). isdebugenabled ()) {
- Context.getlogger (). Debug (
- Sm.getstring ("Coyoterequest.parseparameters"), e);
- }
- return;
- }
- Parameters.processparameters (formData, 0, Len); Process the POST request parameter and put it in the Requestparameter map (that is, Request.getparametermap gets the Map,request.getparameter (name) from this map)
- Omit part of the code ...
- }
- 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;
- }
As can be seen from the above code, Content-type is not a application/x-www-form-urlencoded POST request is not to read the request body data and the corresponding parameter processing, that is, the form data will not be parsed into the request Parameter map. So through Request.getparameter (name) is not available.
So how do we get the arguments that are submitted?
Of course it is the most primitive way to read the input stream to get it, as shown below:
[Java] viewplain copy
- 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 ();
- }
Of course, the POST request setting up application/x-www-form-urlencoded can also be obtained in this way.
Therefore, when using the native Ajax POST request, you need to explicitly set the request Header, which is:
[JavaScript] viewplain copy
- Xhr.setrequestheader ("Content-type", "application/x-www-form-urlencoded");
In addition, if I use jQuery, I use 1.11.0 this version to Test , $.ajax POST request is not need to explicitly set this request header, other version of I did not personally tested. It is believed that the version after 1.11.0 is also not required to be set. But it doesn't have to be before. This has not been tested.
2015-04-17 PostScript:
Recently in Reading, really understand, why the server will be the form submission and file upload do special processing, because the form submission data is the way of name value pairs, and Content-type is application/x-www-form-urlencoded, The file upload server needs special processing, the normal POST request (Content-type is not application/x-www-form-urlencoded) data format is not fixed, not necessarily the way of the name value pairs, so the server can not know the specific processing method, Therefore, parsing can only be done by acquiring the original data stream.
jquery sets Content-type to application/x-www-form-urlencoded when executing a POST request, so the server can parse correctly, and when using native AJAX requests, If the settings are not displayed Content-type, then the default is Text/plain, then the server does not know how to parse the data, so only by acquiring the original data stream to parse the request data.
When the background uses @requestbody to receive data as an object, the foreground must be passed as Application/json, using json.stringify (data) to convert the JSON object to a JSON string.
When you use the application/x-www-form-urlencoded format to pass data, Tomcat assembles it into a map that can only be accessed by Request.getparameter in the background.
Native AJAX default format: Text/plain
Jquery ajax default Format (MAP) + form form Post submission format: application/x-www-form-urlencoded
Character Stream Ajax Format (MAP): Application/json (using json.stringify (data) to convert a JSON object to a JSON string)
File Upload: Multipart/form-data
Ajax's Text/plain, application/x-www-form-urlencoded, and Application/json