@The difference between RequestBody and @ RequestParam is comprehensive and detailed

@RequestParam

The parameter received by annotation @ RequestParam comes from the requestHeader, that is, the request header.

RequestParam can accept properties of simple types or object types.

@RequestParam has three configuration parameters:

Required indicates whether it is required. The default value is true and must be.
defaultValue to set the default value of the request parameters.
Value is the parameter name of the receiving url (equivalent to the key value).

@RequestParam is used to process content whose content type is application/x-www-form-urlencoded. Content type is this attribute by default@ RequestParam can also be used for other types of requests, such as POST, DELETE and so on.

Therefore, in postman, the type of body should be selected as x-www-form-urlencoded, which will automatically change to content type: application / x-www-form-urlencoded encoding format in headers.
However, this does not support batch data insertion. If you use json string to transfer values, the type is set to application/json. If you click send, an error will be reported. The value cannot be received in the background and is null.

At this time, the annotation @ RequestBody comes in handy. Keep looking down

@RequestBody

The annotation @ requestBody receives parameters from the requestBody, that is, the request body. It is generally used to process data in non content type: application / x-www-form-urlencoded encoding format, such as application/json, application/xml and other types of data.

For application/json data, the annotation @ RequestBody can be used to transfer all json data in the body to the back end, which can then be parsed.

In the GET request, @ RequestBody is not applicable because there is no HttpEntity.

In the POST request, the parameters passed through HttpEntity must declare the data type content type in the request header. Spring MVC uses

The HandlerAdapter configures HttpMessageConverters to parse the data in HttpEntity, and then binds it to the corresponding bean.

Batch insert data into table

As an example of batch inserting data, the Controller layer is written as follows:

Since @ RequestBody can be used to process content with content type encoded by application/json, in postman, select the type of body as row - > JSON (application/json), which will automatically change to content type: application/json encoding format in Headers. The data in the body is shown in the figure below:

Insert two pieces of data into the table in batch. The saveBatchNovel() method here has encapsulated the saveAll() method of JPA. The key value of the json statement in the body should correspond to the attributes of the back-end entity class one by one.

Note: the front end uses $ For ajax, you must specify contentType: "application/json;charset=utf-8;", The default is application/x-www-form-urlencoded.

Back end parsing json data

The above example is the specific writing method passed to the entity class. If it is passed to the non entity class, how should the json data in the body be parsed? Let's take another look at the following example:

In the body, we still input the above json data. According to the analysis, the above json data is a List array embedded with a map object, so the receiving form in the background can be written as List < map < string, string > >. The specific code is shown in the following figure:

postman request:

Console output:

It is concluded that the json format data in the Body can be parsed through @ RequestBody.

?
?

On POST request

@Requestbody -- > JSON string part

@Requestparam -- > request parameter part

application/json pattern

Form data and x-www-form-urlencoded pattern

?

1. Summary from content type:

① Form data, x-www-form-urlencoded: @ RequestBody is not allowed; You can use @ RequestParam. See the pattern of postman. There is no json string part in these two methods.

② application/json: the string part of json can use @ RequestBody; In the url? The following parameters can use @ RequestParam. See postman's pattern

?

2. Summarize from two annotation methods:

@RequestBody
(@RequestBody Map map)
(@RequestBody Object object)
application/json When available
form-data,x-www-form-urlencoded When not available
@RequestParam
(@RequestParam Map map)
application/json When, json The string part is not available, url Medium?Parameters added later are available, form-data,x-www-form-urlencoded When available, but to Headers Inside Content-Type Delete
(@RequestParam String waterEleId,@RequestParam String enterpriseName)
application/json When, json The string part is not available, url Medium?Parameters added later are available
form-data,x-www-form-urlencoded When available, and the parameters can be out of order (i.e. the parameters passed from the front end or url The order of parameters in does not have to be the same as that in the background interface, as long as the field names are the same), but Headers Inside Content-Type Delete
(@RequestParam Object object)
Ignore application/json,form-data,x-www-form-urlencoded Not available
It is neither @ RequestBody nor @ RequestParam, and the parameter receiving method is not specified
(Map map)
(Object object)
application/json Time: json The string part is not available, url Medium?Parameters added later are not available.
Because there is no specification, it doesn't know what to use json String part or?The parameter part is added later, so it can't be used at all
form-data,x-www-form-urlencoded It is not available at any time, as shown in Figure II

(HttpServletRequest request)
application/json Not available
form-data,x-www-form-urlencoded Available when

GET request

@RequestBody
RequestBody -- Map / Object
GET Cannot be used in request@RequestBody
@RequestParam
(@RequestParam Map map)
stay url Medium?You can use it by adding parameters later
(@RequestParam String waterEleId,@RequestParam String enterpriseName)
stay url Medium?You can use it by adding parameters later
(@RequestParam Object object)
GET Cannot be used in request

When a GET request is used, you can add "GET" through postman? The following parameters do not need to be spelled one by one in the url. Click Params and enter in the key value below to automatically splice them into the url

Ju Liezi
Upload the file, including the two parts circled in the figure

If so, there is no @ RequestParam, then what is the url? You can't get the parameters after

@RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
    public ResponseObj<Boolean> leadingIn(Map formData,
                                          HttpServletRequest request,
                                          Map<String, InputStream> files) {
}

If it is received in this way in the control, you originally wanted formData to only receive URLs? After the parameter, the result will be {"retCode": null, "data": true}. This part of the content has also been obtained. It is a real and unexpected joy. The string can also be obtained from the request. See the complete method below.

@RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
    public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
                                          HttpServletRequest request,
                                          Map<String, InputStream> files) {
}
Complete method
 /**
     * Import
     */
    @RequestMapping(value = "/leadingIn", method = RequestMethod.POST)
    public ResponseObj<Boolean> leadingIn(@RequestParam Map formData,
                                          HttpServletRequest request,
                                          Map<String, InputStream> files) {
        //test
        try {
            MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
            Set<Map.Entry<String, MultipartFile>> set = mulRequest.getFileMap().entrySet();
            Map<String, InputStream> listFile = new LinkedHashMap<>();
            System.out.println("number" + set.size());
            for (Map.Entry<String, MultipartFile> each : set) {
                String fileName = each.getKey();
                MultipartFile file = each.getValue();
                //You need to upload FTP here
                try {
                    listFile.put(fileName, file.getInputStream());
                } catch (Exception ex) {
                    return new ResponseObj<>(false, null);
                }
            }

            String formjson = mulRequest.getParameter("content");
            ObjectMapper mapper = new ObjectMapper();
            mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

//            boolean result = iInstallWorkOrder.upLoadFile(listFile);
            boolean result = true;

            return new ResponseObj<>(result, null);
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return new ResponseObj<>(false, null);
        }

    }

Press F12 to see the corresponding request in the Network:

Use @ RequestParam: content type as application/x-www-form-urlencoded, and the parameters are in FormData

Use @ RequestBody: content type as application/json, and the parameters are in Request PayLoad

summary

1.  stay GET Cannot use in request@RequestBody
2. stay POST Request, can use@RequestBody and@RequestParam,But if you use@RequestBody,For parameter conversion			 The configuration of must be uniform.
3. Multiple can be used@RequestParam Get data,@RequestBody may not 
3.1 title for example
	stay SpringMVC Configured HttpMessageConverters In the processing stack, specify json Format of conversion, such as Date Turn into'yyyy-MM-dd',If yes, the field contained in the parameter receiving object Date Type, the client can only pass the format of year, month and day, not hours, minutes and seconds. Because the parameters of different interfaces may have different format requirements for time parameters, doing so will make the client calling colleagues a little confused about the format of parameters, so the scalability is not high. If used@RequestParam To accept parameters, you can model Medium setting@DateFormat Specifies the format of the time parameter to be accepted. In addition, use@RequestBody The accepted parameters will not be Servlet The transformation is unified in request Object Param Parameter set,@RequestParam Yes. 
4. In addition, there is another application scenario. The interface specification is resultful Style, for example: if you want to get a id If the number of queries for the answer to this question is, the background needs to dynamically obtain the parameters, and its annotation is@PathVariable,also requestMapping Medium value Should be value="/{id}/queryNum",

reference resources:

@Detailed explanation of parameter binding annotation such as RequestParam @RequestBody @PathVariable

https://blog.csdn.net/walkerjong/article/details/7946109

https://my.oschina.net/u/3372000/blog/906217

https://www.jianshu.com/p/4981911d5e15

https://cloud.tencent.com/developer/article/1414464

Keywords: Java Spring https

Added by maca134 on Wed, 09 Feb 2022 04:54:20 +0200