SpringMVC-a summary of the practice of the HTTP request project

(1) Introduction to MIME

(1 Introduction

Grammatical structures

type/subtype         类型/独立类型

A media type (often referred to as Multipurpose Internet Mail Extensions or MIME type) is a standard used to express the nature and format of a document, file, or byte stream. It is defined and standardized in IETF RFC 6838.

Important: Browsers usually use the MIME type (rather than the file extension) to determine how to handle the URL, so it is very important for the web server to add the correct MIME type in the response header. If the configuration is incorrect, the browser may distort the content of the file, the website will not work properly, and the downloaded file will be processed incorrectly.

The composition structure of MIME is very simple; it is composed of two strings of type and subtype separated by a'/'. No spaces are allowed. type represents an independent category that can be divided into multiple subcategories. subtype represents each type after subdivision.

The MIME type is not case sensitive, but the traditional way of writing is lowercase.

(2) Independent type
text/plain
text/html
image/jpeg
image/png
audio/mpeg
audio/ogg
audio/*
video/mp4
application/*
application/json
application/javascript
application/ecmascript
application/octet-stream

Insert picture description here

If there is no specific subtype for the text file type, text/plain is used. Similarly, the binary file has no specific or known subtype, that is, application/octet-stream is used.

(2) Four common POST data submission methods

The protocol stipulates that the data submitted by POST must be placed in the entity-body, but the protocol does not specify what encoding method the data must use. In fact, developers can completely decide the format of the message body by themselves, as long as the last HTTP request sent meets the above format.

However, for the data to be sent out, it only makes sense for the server to parse successfully. Common 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 knows how the message body in the request is encoded according to the Content-Type field in the request headers, and then parses the body. So when it comes to the POST data submission scheme, it includes two parts: Content-Type and the encoding method of the message body. Let's start to introduce them formally.

[Application/x-www-form-urlencoded]
This should be the most common way to submit data via POST. The browser’s native form, if the enctype attribute is not set, then it will end up with

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

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

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

[Multipart/form-data]
This is another common way of POST data submission. When we use the form to upload files, the enctype of the form must be equal to multipart/form-data.
[Application/json]

The Content-Type of application/json is certainly 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 lower versions of IE natively support JSON.stringify, and server-side languages ​​also have functions for processing JSON, so you will not encounter any trouble using JSON.

The JSON format supports structured data that is much more complex than key-value pairs, which is also useful.

[Text/xml]
It is a remote call specification that uses HTTP as the transmission protocol and XML as the encoding method. A typical XML-RPC request looks like this:

POST 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, functional and can be implemented 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 the existing XML-RPC services. However, I personally feel that the XML structure is still too bloated, and it is more flexible and convenient to use JSON in general scenarios.

(3) How SpringMVC receives POST requests

(1) Default Content-Type

Content-Type is transmitted in application/x-www-form-urlencoded, the default form.
This transmission method is to construct the normal post request of the form form for transmission
. Two parameters are required in the controller. At the same time, please note that this cannot be added @RequestBody Otherwise, a 405 exception will be thrown, and the parameters will be filled into the parameters in the form of strings and arrays

application/x-www-form-urlencoded receiving method:

1:@RequestParam(“name”)

2: Use the same key name string to receive String name, the name needs to match

3: Use the entity class to receive, the matched attribute will inject the value, the setgeter method is required, and the name is inconsistent and cannot be injected

4: Use request.getParameter("name"); to receive

(2)application/json

Content-Type is transmitted in the form of application/json. In
this way, a json format string
needs to be transmitted. The controller needs to use a string to accept the json string.
If you use annotations, you need to add @RequestBody.
If you don’t need annotations, you need to Read the body content in the request field, and then deserialize this string into json into an object. If you want it to be automatically converted into an object, you need to configure the json serialization tool in the SpringMVC configuration.

The reference method is as follows:

1: Use @RequestBody String to receive, directly to a String can not be received, this way receives a JSON string, you need to convert it by yourself

2: @RequestBody plus POJO receiving or string

3: @RequestBody Map<String,Object> json, it is more convenient to use Map to receive, no need to build VO object

4: Manually obtain getReader() or getInputStream() from the stream. Note that the bottom layer of the previous method is also received in this way, and the stream cannot be repeated

Receive parameters: one object with multiple single attributes

(4) The difference between getParameter() getInputStream() and getReader()

request.getParameter()
request.getInputStream()
request.getReader()
These three methods all get the submitted data from the request object, but they have different uses.

Choose different methods according to the encoding method of the form submission data.

A key attribute enctype of the form form in HTML:

(1) Enctype=application/x-www-form-urlencoded
This encoding method is the default encoding method.
The encoded result is usually in the form of field1=value2&field2=value2&..., such as name=aaaa&password=bbbb.
The commonly used forms are also coded in this way. The Servlet API provides support for decoding of this coding method. You only need to call the getParameter() method in the ServletRequest class to get the fields and data in the user form.
Disadvantages:
Although this coding method (application/x-www-form-urlencoded) is simple, it is not capable of transmitting large blocks of binary data.

(2) Multipart/form-data
For data such as large blocks of binary numbers, the browser uses another encoding method, namely the "multipart/form-data" encoding method:

The browser can easily send the data and files in the form together. This encoding method first defines a string that cannot appear in the data as a delimiter, and then uses it to separate each data segment, and each data segment corresponds to an Input area in the HTML page form, including one The content-disposition attribute indicates some information of this data segment. If the content of the data segment is a file, there will also be a Content-Type attribute, and then the data itself. If you submit data in this way, you need to use request.getInputStream () or request.getReader() to get the submitted data, using request.getParameter() cannot get the submitted data.

The three methods request.getParameter(), request.getInputStream(), and request.getReader() are in conflict, because the stream can only be read once.
For example:
when the form content is encoded with enctype=application/x-www-form-urlencoded, first get the parameters by calling the request.getParameter() method, and then call request.getInputStream() or request.getReader(). To the content in the stream, because the system may read the data submitted in the form once in the form of a stream when request.getParameter() is called, and vice versa.

When the form content is encoded with enctype=multipart/form-data, no data can be obtained even if request.getParameter() is called first, so the request.getParameter() method is called to request.getInputStream() or request.getReader(). ) There is no conflict, even if the request.getParameter() method has been called, the data in the form can be obtained by calling request.getInputStream() or request.getReader(), and request.getInputStream() and request.getReader() are in the same The response cannot be mixed, and if mixed, an exception will be thrown.

In the http request, there are Header and Body. To read the header, use request.getHeader("..."); to read the Body, use request.getReader(), but getReader obtains a BufferedReader, which needs to be converted into a string.

 private static String getPostData(HttpServletRequest request) throws IOException {
    
    
     StringBuilder data = new StringBuilder();
     String line;
     BufferedReader reader;
     try {
    
    
         reader = request.getReader();
         while (null != (line = reader.readLine())) {
    
    
             data.append(line);
         }
     } catch (IOException ignored) {
    
    
         throw new IOException();
     }
     return data.toString();
 }

reference

https://imququ.com/post/four-ways-to-post-data-in-http.html

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types

Guess you like

Origin blog.csdn.net/Octopus21/article/details/110734658