Spring MVC of Hekai Zhenxue Spring boot 3.0: ④ Get parameters (Part 1)

Before, I repeatedly said that the processor encapsulates the controller. After the HandlerMapping mechanism finds the processor, the controller can be run through the processor. So what functions does the processor enhance the controller?

Let's think about it, what do we need to do before running the controller? That must be a parameter of the method. So the first step of the processor is to get the parameters according to our method.

It’s just that the content of getting parameters is a bit too much. I plan to explain it in three articles, so the title here adds a "top"

1. How does Spring MVC get the parameters of calling the controller method?

For the controller, parameters may come from many aspects, such as Session, HTTP request parameters, HTTP request headers, system parameters, request path, etc. Of course, there is also a special request body (it can be a file or JSON, we will talk about it later). In order to be able to handle controller parameters, the Spring MVC processor method parameter resolver (HandlerMethodArgumentResolver), through which parameters from various aspects can be resolved. After getting the parameters, you can call the method of the controller.

To this end, let's first look at which handler method parameter resolvers (HandlerMethodArgumentResolver) Spring MVC provides for us, as shown in the following figure.

Handler Method Argument Resolver (HandlerMethodArgumentResolver)

 Please note that in the above picture, the red boxes I added are all our commonly used parsers, but Spring MVC will erase this step, allowing us to use them unconsciously. We remember this mechanism a little here, and the following content is related to them.

2. Obtain parameters without annotations

In order to explain, I will give a piece of code here as follows:

package com.csdn.mvc.chapter1.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@Controller
// 这个注解可以配置在类或者方法上
@RequestMapping("/param")
public class ParameterController {
    /**
     * 在无注解下获取参数,要求参数名称和HTTP请求参数名称一致,此时允许参数为空
     * @param intVal  -- 整数
     * @param longVal -- 长整型
     * @param strVal --字符串
     * @return 响应JSON参数
     */
    // HTTP GET请求
    @GetMapping("/no/annotation")
    @ResponseBody
    public Map<String, Object> noAnnotation(
            Integer intVal, Long longVal, String strVal) {
        var paramsMap = new HashMap<String, Object>();
        paramsMap.put("intVal", intVal);
        paramsMap.put("longVal", longVal);
        paramsMap.put("strVal", strVal);
        return paramsMap;
    }


}

 Please note that the method here has parameter names of "intVal", "longVal" and "strVal", as long as our HTTP request with these parameters can be obtained. And the method is marked with @ResponseBody, which means that the returned thing will be turned into a JSON dataset.

That is, by default, Spring MVC will automatically match the parameters of the controller method to the request parameters with the same name. This is the role of the handler method parameter resolver (HandlerMethodArgumentResolver), but Spring MVC shields this process, so we can't realize it.

@RequestMapping("/param") is marked on the class, indicating that all requests of this class need to be prefixed with "/param", and @GetMapping is an HTTP GET request. After Spring 4.3, several annotations were added to simplify the configuration of method configuration items, such as @GetMapping, @PostMapping, @PatchMapping, @PutMapping and @DeleteMapping. Corresponding to HTTP GET, POST, PATCH, PUT and DELETE requests, I will discuss these in REST style requests.

Parameters without annotations are allowed to be empty. For example, we request: http://localhost:8080/param/no/annotation?intVal=1&longVal=1

Such a result can be obtained. (Note: the strVal parameter is empty )

3. Use @RequestParam to get parameters

The above is to get the parameters without annotations, but the fact is that the parameters can also be obtained from the request parameters. Because HTTP request parameters and controller method parameters have different names, it is necessary to establish a mechanism to obtain controller parameters from HTTP request parameters. Then use the annotation @RequestParam. It will enable RequestParamMethodArgumentResolver to get parameters.

We add a method to test in ParameterController, as follows

/**
 * 通过@RequestParam获取参数,此时默认不允许参数为空
 * @param intVal  -- 整数
 * @param longVal -- 长整型
 * @param strVal --字符串
 * @return 响应JSON参数
 */
// HTTP GET请求
@GetMapping("/annotation")
@ResponseBody
public Map<String, Object> annotation(
        @RequestParam("int_val") Integer intVal,
        @RequestParam("long_val") Long longVal,
        @RequestParam("str_val") String strVal) {
    var paramsMap = new HashMap<String, Object>();
    paramsMap.put("intVal", intVal);
    paramsMap.put("longVal", longVal);
    paramsMap.put("strVal", strVal);
    return paramsMap;
}

@RequestParam means to obtain parameters from the HTTP request parameters to the controller, "int_val", "long_val" and "str_val" represent the parameter names, and then you can name the parameters of the controller as intVal, longVal, strVal, etc. you want. @RequestParam can correspond to them by name.

Just everyone needs to pay attention, the parameter marked by @RequestParam cannot be empty by default, if it is empty, an exception will be thrown. If you allow it to be empty, you can modify the configuration as follows.

@RequestParam(value="int_val", required = false) Long intVal

The default value of the required configuration item in the code is true, that is, it cannot be defaulted. If it is changed to false, then the default is allowed. Of course, in most cases, I do not recommend that you configure it to avoid throwing the notorious NullPointerException.

4. Obtain parameters from the URL

Many times in REST requests, we need to get parameters from the URL, such as the request:

GET http://localhost:8080/user/1

Get the user information of user number 1 on behalf of us, so the number needs to be obtained from the URL. At this time, you need to use the combination of @PathVariable and URL to achieve. To this end, we add a method to test in ParameterController, as follows

@GetMapping("/path/{intVal}/{longVal}/{strVal}")
@ResponseBody
public Map<String, Object> path(
        @PathVariable("intVal") Integer intVal,
        @PathVariable("longVal") Long longVal,
        @PathVariable("strVal") String strVal) {
    var paramsMap = new HashMap<String, Object>();
    paramsMap.put("intVal", intVal);
    paramsMap.put("longVal", longVal);
    paramsMap.put("str", strVal);
    return paramsMap;
}

The path of @GetMapping here is "/path/{intVal}/{longVal}/{strVal}", these {paramName} formats are the positions of positioning parameters, so you can use @PathVariable({paramName}) in the path() method You can get the parameters in the corresponding URL.

Guess you like

Origin blog.csdn.net/ykzhen2015/article/details/129944882