Four common POST data submission methods --good

Source: http://www.cnblogs.com/softidea/p/5745369.html
Comments:
The HTTP request methods specified by the HTTP/1.1 protocol include OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, and CONNECT. Among them, POST is generally used to submit data to the server. This article mainly discusses several ways to submit data through POST.

We know that the HTTP protocol is an application layer specification based on the TCP/IP protocol, which is transmitted in ASCII code. The specification divides the HTTP request into three parts: the status line, the request header, and the message body. Similar to the following:

BASH <method> <request-URL> <version>
<headers>

<entity-body>

The protocol stipulates that the data submitted by POST must be placed in the message body (entity-body), but the protocol does not stipulate that the data must be What encoding to use. In fact, the developer can completely decide the format of the message body, as long as the final HTTP request satisfies the above format.

However, when the data is sent out, it only makes sense if the server parses it successfully. General server languages ​​such as php, python, etc., as well as their frameworks, have built-in functions to automatically parse common data formats. The server usually learns how the message body in the request is encoded according to the Content-Type field in the request header, and then parses the body. So when it comes to the POST submission data scheme, it includes two parts: Content-Type and message body encoding method. The following is the official introduction to them.
application/x-www-form-urlencoded

This should be the most common way of POSTing data. The browser's native <form> form, if the enctype attribute is not set, will eventually submit data in the form of application/x-www-form-urlencoded. The request looks like the following (irrelevant request headers are omitted in this article):

BASHPOST 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

First, the Content-Type is specified as application/x-www-form-urlencoded; secondly, the submitted data is based on key1=val1&key2= val2 is encoded, and both key and val are URL transcoded. Most server-side languages ​​have good support for this approach. For example, in PHP, $_POST['title'] can get the value of title, and $_POST['sub'] can get the sub array.

Many times, we also use this method when we submit data with Ajax.
For example, Ajax of JQuery and QWrap, the default value of Content-Type is "application/x-www-form-urlencoded; charset=utf-8".
multipart/form-data

This is again a common way of POST data submission. When we upload files using a form, we must let <form> The enctyped of the form is equal to multipart/form-data. Just look at an example request:

BASHPOST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

This example is a little more complicated. First, a boundary is generated to separate different fields. In order to avoid duplication with the body content, the boundary is very long and complicated. Then Content-Type indicates that the data is encoded in multipart/form-data, and what is the boundary of this request. The message body is divided into several parts with similar structure according to the number of fields. Each part starts with --boundary, followed by content description information, then carriage return, and finally the specific content of the field (text or binary). If transferring a file, also include file name and file type information. The message body ends with the --boundary-- flag. For the detailed definition of multipart/form-data, please go to rfc1867.

This method is generally used to upload files, and major server languages ​​also have good support for it.

The two methods of POST data mentioned above are natively supported by browsers, and the native <form> form in the current standard only supports these two methods (specified by the enctype attribute of the <form> element, the default is application/x-www-form-urlencoded. In fact, enctype also supports text/plain, but it is used very rarely).

As more and more Web sites, especially WebApps, all use Ajax for data interaction, we can define new data submission methods to bring more convenience to development.
Application/json

application/json This Content-Type is no stranger to the response header. In fact, more and more people now use it as a request header to tell the server that the message body is a serialized JSON string. Due to the popularity of the JSON specification, all major browsers except low-level IE natively support JSON.stringify, and the server-side languages ​​also have functions for processing JSON, so you will not encounter any trouble when using JSON.

It is also useful that the JSON format supports structured data that is much more complex than key-value pairs. I remember that when I was working on a project a few years ago, the data that needed to be submitted was very deep, and I submitted the data after serializing it in JSON. But at that time, I used the JSON string as val, still put it in the key-value pair, and submitted it in the form of x-www-form-urlencoded.

The Ajax function in Google's AngularJS, the default is to submit a JSON string. For example the following code:

JSvar data = {'title':'test', 'sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
    .. .
});

The final request sent is:

BASHPOST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8

{"title":"test","sub":[ 1,2,3]}

This solution can easily submit complex structured data, especially suitable for RESTful interfaces. Major package capture tools, such as Chrome's own developer tools, Firebug, and Fiddler, will display JSON data in a tree structure, which is very friendly. But some server-side languages ​​do not yet support this method. For example, php cannot get the content from the above request through the $_POST object. At this time, you need to handle it yourself: when the Content-Type in the request header is application/json, from php: //Get the original input stream in input, and then json_decode it into an object. Some php frameworks have started to do this.

Of course, AngularJS can also be configured to submit data using x-www-form-urlencoded. If necessary, you can refer to this article.
text/xml

My blog mentioned XML-RPC (XML Remote Procedure Call) before. It is a remote invocation specification that uses HTTP as the transport protocol and XML as the encoding method. A typical XML-RPC request looks like this:

HTMLPOST http://www.example.com HTTP/1.1
Content-Type: text/xml

<?xml version="1.0"?>
<methodCall>
    <methodName>examples.getStateName< /methodName>
    <params>
        <param>
            <value><i4>41</i4></value>
        </param>
    </params>
</methodCall>

The XML-RPC protocol is simple and functional, and there are implementations in various languages. It is also widely used, such as the XML-RPC Api of WordPress, the ping service of search engines and so on. In JavaScript, there are also ready-made libraries that support data interaction in this way, which can well support existing XML-RPC services. However, I personally think that the XML structure is still too bloated, and JSON is more flexible and convenient in general scenarios.

Link to this article: https://imququ.com/post/four-ways-to-post-data-in-http.html, participate in comments »

--EOF--


rest api parameters and content-type

recently provided rest for project groups When api encountered the transfer of interface parameters, the main reason was that the use of third-party callers was not fully considered. We should try our best to be compatible with the interface calling methods provided by the company before, so as to reduce the learning cost of third-party callers. Although the previous approach is not so recommended, it is good practice to support the recommended approach while being compatible with the old approach.

For the http post-based interface, I would prefer application/json for Content-type, but the interface provided by the company just adopted application/x-www-form-urlencoded, which is the default submission type of the form, which is submitted based on the key/value form to the server. How does spring mvc receive the following two classic data? (As for form-data, it can either pass key-value pairs or upload files. Files are not involved here, so only the following two are discussed):

    Content-type=application/json : The annotation @RequestBody needs to be added to the parameter, indicating that the parameter is obtained from the http requestbody.

The parameters in the figure below are in standard json format, which is very friendly to front-end js.

    Content-type=application/x-www-form-urlencoded, the annotation

of . As shown in the figure below, it can be seen that the parameter format is the same as the parameter format after the URL when the get request is made.


Why is application/x-www- This type of form-urlencoded has the following problems:

    If the test is difficult, don't even think about testing it with tools such as postman: the submission to the server is actually a MultiValueMap (org.springframework.util.MultiValueMap). If the object in the value is also an object, it is very difficult to construct this parameter , take a look at its process. It
        uses the form of key1=value1&key2=value2 to splicing all parameters together. If you want to understand the meaning of each parameter from a long string of characters, you may not have good eyesight.
        The value needs to be encoded, and the encoded value is not friendly to debuggers.
        The situation is even worse when the value is a complex object. Generally, the parameters can only be serialized through the program, and it is basically impossible to write by hand.
    Complex client calls

need to build List<NameValuePair>. Generally, the parameters passed by the page are an entity object Model. It is necessary to additionally convert this Model into List<NameValuePair>. If the object is complex, then constructing this Key/Value is enough. People are annoying. Here is a comparison of java calls through apache httpclient to see which one is simpler.

        application/x-www-form-urlencoded

needs to manually convert the model to NameValuePair.

        Application/json

only needs Model here, no secondary conversion is required, and the structure is very clear.

    The language expression of key/value is not as strong as json. Which of the following two do you prefer?
        string

In tools such as post man that mimic http requests, if the value corresponding to the key is an object, then you need to get its serialized string through the tool and fill it in the field, which is annoying to think about. If you say that I don't need to pass these simulation tool tests, then it's another matter that the

        json

    data structure is more complex.

If the objects to be submitted are very complex and have many attributes, if all attributes are built into MultiValueMap, the construction of that Map It will be very complicated, imagine if the object has multiple levels of nested objects. In order to avoid this problem, we store the business object that needs to be submitted as a key, and the value is the string after the object is serialized. Adding some non-business parameters, such as security tokens and other parameters, effectively reduces the complexity of MultiValueMap construction. But this method is deeper than the json delivery method. As shown in the figure below, our parameters have one more layer, jsonParam.



What if it was resolved?
It cannot be incompatible with the existing mode, but I want to support json. The focus is on the reception of parameters, so that it can be perfectly compatible with the above two parameter transmissions. Here we can start with HttpMessageConverter, which is used to map the requested parameters to Entity parameter in spring mvc method. We can write a custom class that internally borrows FormHttpMessageConverter to receive MultiValueMap. Even if the @RequestBody annotation is added to the method parameters, we will use our custom converter and have the opportunity to reassign the parameters.

There is a problem to be solved in this method, that is, each parameter is processed as a string when the client passes it, which leads to that when we convert it into a Map through the FormHtppMessageConverter, the original property of the object is recognized as a string, not an object , the result is an error when deserializing. Fortunately, above we wrapped the object to be submitted once to generate a public object parameter jsonParam, and only need to process this special object. The method is to take jsonParam from the Map, then deserialize its content, update the Map value, and deserialize it again.

The practice in the above figure currently has the following problems

    . The serialized fields are agreed and are basically processed based on our post model. It is
    the convertValue of jackon called at the end of the targeted converter code, which is for the object that needs to be deserialized. The type has requirements, and it seems that generic types are not supported. For example, this type of type does not work: CommonParamInfoDto<SearchParamInfo<ProductSearchInfo>>

The complete conveter code is as follows, in fact, the main code is the serialization of specific fields as shown in the map above, All other methods are default.
Copy Code
Copy Code

public class ObjectHttpMessageConverter implements HttpMessageConverter<Object> {

    private final FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
    private final ObjectMapper objectMapper = new ObjectMapper();

    private static final LinkedMultiValueMap<String, ?> LINKED_MULTI_VALUE_MAP = new LinkedMultiValueMap<>();
    private static final Class<? extends MultiValueMap<String, ?>> LINKED_MULTI_VALUE_MAP_CLASS
            = (Class<? extends MultiValueMap<String, ?>>) LINKED_MULTI_VALUE_MAP.getClass();

    @Override
    public boolean canRead(Class clazz, MediaType mediaType) {
        return objectMapper.canSerialize(clazz) && formHttpMessageConverter.canRead(MultiValueMap.class, mediaType);
    }

    @Override
    public boolean canWrite(Class clazz, MediaType mediaType) {
        return false;
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return formHttpMessageConverter.getSupportedMediaTypes();
    }


    @Override
    public Object read(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        Map input = formHttpMessageConverter.read(LINKED_MULTI_VALUE_MAP_CLASS, inputMessage).toSingleValueMap();
        String jsonParamKey="jsonParam";
        if(input.containsKey(jsonParamKey)) {
            String jsonParam = input.get(jsonParamKey).toString();
            SearchParamInfo<Object> searchParamInfo = new SearchParamInfo<Object>();
            Object jsonParamObj = JsonHelper.json2Object(jsonParam, searchParamInfo.getClass());
            input.put("jsonParam", jsonParamObj);
        }
        Object objResult= objectMapper.convertValue(input, clazz);
        return objResult;
    }

    @Override
    public void write( Object o, MediaType contentType, HttpOutputMessage outputMessage) throws UnsupportedOperationException {
        throw new UnsupportedOperationException("");
    }
}

Copy code
Copy code



Configuration, after writing the converter, it needs to be configured in the configuration file to take effect.



Finally, our method can be written like this, which can support key/value pairs and json

My purpose is that the parameters of the api can support both application/x-www-form-urlencoded and application/json. The above is the way I can think of at present. If you have other better ways, please give me some pointers.



I can happily test with post man again. And third-party callers can be recommended to use json first, and I believe that the advantages of simplifying programming and easy debugging should be able to attract them.

http://www.cnblogs.com/ASPNET2008/p/5744815.html





<form> should add the attribute enctype="multipart/form-data" in the form for uploading files, many people just know by rote how to write the upload form like this , know it but don't know why. So why add this property? What does it mean? What other optional values ​​does it have? In fact, when you do not write the enctype attribute in the form form, the enctype attribute value is added to it by default. The default value is enctype="application/x-www-form-urlencoded". This attribute manages the MIME encoding of the form. There are three Optional values:

  ①application/x-www-form-urlencoded (default)
  ②multipart/form-data
  ③text/plain


  Among them, ①application/x-www-form-urlencoded is the default value. You may have seen this in AJAX: xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); It does the same thing, it sets the encoding for the form transfer. If it is not written in AJAX, an error may be reported, but in the HTML form form, enctype="application/x-www-form-urlencoded" can be omitted, because the default HTML form is this transfer encoding type. And ②multipart-form-data is used to specify a special type of transmission data, mainly non-text content we upload, such as pictures or mp3 and so on. ③text/plain means plain text transmission. This encoding type should be set when sending emails, otherwise there will be a problem of confusing encoding when receiving. Text/plain and text/html are often compared on the Internet. In fact, these two are very different. It is easy to distinguish, the former is used to transmit plain text files, and the latter is the encoding type of the html code, which is only used when sending header files. ① and ③ cannot be used to upload files, only multipart/form-data can transmit file data completely.

  The MIME mentioned above, its full English name is "Multipurpose Internet Mail Extensions" Multipurpose Internet Mail Extensions Service, it is a multipurpose Internet Mail Extensions protocol, first applied to email systems in 1992, but later also applied to browser. The server will tell the browser the type of multimedia data they send, and the notification means is to indicate the MIME type of the multimedia data, so that the browser knows which of the received information is an MP3 file, which is a Shockwave file, and so on. The server puts MIME identifiers in the transmitted data to tell the browser which plugin to use to read the associated file.

  Simply put, a MIME type is a way to set a file with a certain extension to be opened by an application. When the extension file is accessed, the browser will automatically use the specified application to open it. It is mostly used to specify some client-defined file names, as well as some media file opening methods.

  After the browser receives the file, it will enter the plug-in system to find out which plug-in can recognize and read the received file. If the browser doesn't know which plug-in system to call, it may tell the user that a plug-in is missing, or simply select an existing plug-in to try to read the received file, which may crash the system. It is difficult to estimate the possible consequences of the absence of MIME identifiers in the transmitted information, as some computer systems may not malfunction, but some computers may crash as a result.


The steps to check if a server has the correct MIME type are:

  1. Open the server web page in Netscape browser
  2. Go to the "View" menu and select "Page Info"
  3. Click "EMBED" in the upper frame in the pop-up window "
  4. Check whether the MIME type is "application/x-director" or "application/x-shockwave-flash" in the lower frame
          , if it is the above information, it means that the server has correctly set the MIME type; and if the MIME type is listed as text content, octet data or other forms, it means that the server's MIME type is not set correctly.

  If the server does not correctly indicate the type of data it is sending, the server administrator should add the relevant information correctly, which is very simple and quick.

  Each MIME type consists of two parts, the front is a large category of data, such as audio audio, image image, etc., and the specific type is defined in the back.

  Common MIME Types

    Hypertext Markup Language text.html,.html text/htmlplain

    text.txt text/plain

    RTF text.rtf application/rtf

    GIF graphics.gif image/gif

    JPEG graphics.jpeg,.jpg image/jpeg

    au sound file.au audio /basic

    MIDI music file mid,.midi audio/midi,audio/x-midi

    RealAudio music file.ra, .ram audio/x-pn-realaudio

    MPEG file.mpg,.mpeg video/mpeg

    AVI file.avi video/x -msvideo

    GZIP file.gz application/x-gzip

    TAR file.tar application/x-tar

    There is a special organization on the Internet, IANA, to confirm the standard MIME types, but the Internet is developing so fast that many applications cannot wait for IANA to confirm that the MIME types they use are standard types. So their use of methods starting with x- in the category to identify the category is not yet standard, eg: x-gzip, x-tar, etc. In fact these types are so widely used that they have become the de facto standard. As long as the client and the server recognize this MIME type, it does not matter even if it is a non-standard type, the client program can use specific processing methods to process data according to the MIME type. The standard and common MIME types are set by default in Web servers and browsers (including operating systems). Only for uncommon MIME types, both server and client browsers need to be set for identification.
-------------------------------------------------- --------------
The meaning of enctype="multipart/form-data" in the form is to set the MIME encoding of the form. By default,
this encoding format is application/x-www-form-urlencoded, which cannot be used for file uploading;
only when multipart/form-data is used, the file data can be completely transmitted, and the following operations can be performed.
enctype="multipart/form -data" is to upload binary data; the input value in the form is passed in binary format.
The value of the input in the form is passed in binary format,
so the request will not get the value. That is to say, if this code is added, the request will be unsuccessful. When adding the form value to the database, use the following:

SmartUpload su = new SmartUpload();
su.getRequest().getParameterValues(); take an array value
su.getRequest().getParameter( ); take a single parameter and a single value




in application/x-www-form-urlencoded in ajax

1. Basic knowledge of HTTP upload

In the syntax of the Form element, EncType indicates the format of the submitted data. Use the Enctype attribute to specify the encoding type used by the browser when sending the data back to the server. Below is the description: application/x-www-form-urlencoded: Form data is encoded as name/value pairs. This is the standard encoding format. multipart/form-data: Form data is encoded as a message, and each control on the page corresponds to a part of the message. text/plain: The form data is encoded in plain text without any controls or formatting characters.
The enctype attribute of the supplementary
form is the encoding method. There are two commonly used methods: application/x-www-form-urlencoded and multipart/form-data. The default is application/x-www-form-urlencoded.

When the action is get, the browser uses the x-www-form-urlencoded encoding method to convert the form data into a string (name1=value1& amp;name2=value2...), and then append the string to the url Later, split with ? to load this new url.

When the action is post, the browser encapsulates the form data into the http body and sends it to the server.

If there is no type=file control, use the default application/x-www-form-urlencoded. But if there is type=file, it is necessary to use multipart/form-data.
The browser will divide the entire form in units of controls, and add Content-Disposition (form-data or file), Content-Type (default is text/plain), name (control name) and other information to each part, and Add a delimiter (boundary).

2. Things to pay attention to

in uploading data to the server through AJAX, set the content-type to application/x-www-form-urlencoded. At this time, the entire sent content is encoded, not the value corresponding to the name. coded. Therefore, on the server side, it is problematic to obtain the value by request.getParameter("name").

There are two solutions:

1) Change the server side: use the stream method to hard code
Copy code

InputStream stream=request.getInputStream();
InputStreamReader isr=new InputStreamReader(stream);
BufferedReader br=new BufferedReader(isr);
String str= br.readLine();
System.out.println(str);

str=URLDecoder.decode(str,"gb2312");
System.out.println(str);
br.close();

Copy code



2) Change the client: change the data transmission structure

When sending data to the server, use the method of name=escape(value) to group the pair

at this time . In the server code, the value obtained through request.getParameter("name") does not need to be encoded

application/x-www-form-urlencoded, multipart/form-data, text/plain

http://www.cnblogs.com/ mumue/archive/2012/05/24/2515984.html

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326647240&siteId=291194637