Basic understanding and application of Spring Controller

Note: This article is an upload of notes from the previous beginner period. If there are any mistakes, please point them out and correct them. Thank you for your support! If you are interested, you can also follow my blog: yumuing blog

Controller related introduction

Controller in spring represents the control layer, which distributes visitor requests and calls different functions to control the acquisition of request parameters and return the data processed by the business layer to the visitor. It must add the @Controller annotation before the Controller class in spring to inject it into the container and play a role.

There are two ways to pass parameters in the Controller. The first is to add the ? parameter after the path, and the second is to write the parameters directly to the path, as follows:

The first type: yumuing/params?username=yumuing&password=1234

The second type: yumuing/user/{userId}

In the Get request, the way to get the first parameter is mainly to use the @RequestParam annotation to get the parameter with the same name, and the way to get the second parameter is to use the @PathVariable annotation to get the parameter with the same name marked in curly braces in @RequestMapping , among them, @RequestParam and @PathVariable are both written as method parameters, and the parameter type (such as String) must be indicated. @RequestMapping is the overall annotation of the method. When adding new parameters, the path must be specified using path instead of a Simple string writing is enough, as follows:

//第一种
@RequestMappingpath="/params",method=RequestMethod.GETpath = {
    
    "/params"},method = {
    
    RequestMethod.GET}path="/params",method=RequestMethod.GET
public void params@RequestParam(name="username",required=false,defaultValue="test"@RequestParam(name = "username", required = false,defaultValue = "test"@RequestParam(name="username",required=false,defaultValue="test"String username);
//第二种
@RequestMappingpath="/user/userId",method=RequestMethod.GETpath = "/user/{userId}",method = {
    
    RequestMethod.GET}path="/user/userId",method=RequestMethod.GET
public void params@PathVariable("userId"@PathVariable("userId"@PathVariable("userId" int userId);

Of course, there are many parameters of @RequestMapping, but one thing to note is to use curly braces as much as possible (that is, {}, which will be more intuitive and prevent some parameters that must require curly braces from making mistakes, and this annotation can be used as a function, You can also annotate a class. When annotating a class, all methods in the class will be filtered on this basis. The parameter types basically include the following:

  • path: path parameter, the writing format refers to the string in the url suffix format (ie "/yumuing/user"). The parameter specifies the specific path to access the method. When the parameter name is not specified, the default is to fill in the parameter content of path, path Can also be an undefined variable.
  • method: Access method parameters, mainly including Get (RequestMethod.GET), Post (RequestMethod.POST), Delete (RequestMethod.DELETE), Put (RequestMethod.PUT), etc., are all filled in by calling.
  • params: request parameters, which cannot be defined repeatedly with the parameters in RequestParam, there will be conflicts, and there is no priority. The writing format is a string, such as "yumuing"

According to the above three parameters, we can make a controller distinguish and process corresponding requests by requesting url, parameters, and access methods, and call different functions respectively to return the required results.

If you want to perform simple print verification in the browser, you can consider adding @RequestBody before the corresponding Controller function, and specify the return parameter as String, it will only print the returned String data without rendering and so on . If @RequestBody is not used, HTML data will be returned by default.

Of course, @RequestBody can also be used as a function parameter to only accept the content of the request body after specifying that the method can only use Post requests. The different @RequestParam is to receive and parse the data in key-value format in the request body. Both can be used at the same time, also can be used alone.

//打印示例
@RequestMapping("/hello")
@ResponseBody
public String hello() {
    
    
    return "hello";
}

The returned results are basically divided into two types, one is data, and the other is template. The data can be a simple int type, json type, or even other types, and the template is the jsp, html, etc. passed to the browser for rendering. content in other formats.

In thymeleaf, template files are placed in resources/templates by default, and subdirectories can exist. The basic configuration of the template file is as follows:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <!-- xmlns:th="http://www.thymeleaf.org"设置读取该模板文件 -->
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
 	<!--具体内容  -->
    <!-- 示例内容 -->
     <p th:text="${name}"></p>
     <p th:text="${age}"></p>
    <!-- th:text="${age}"匹配对应内容 -->
</body>
</html>

The template data that is finally responded to the browser is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
  <p>hhhh</p>
  <p>30</p>
</body>
</html>

Controller access template file example:

@RequestMapping(path = "/test",method = RequestMethod.GET)
public ModelAndView test(){
    
    
    ModelAndView mav = new ModelAndView();
    mav.addObject("name","hhh");
    mav.addObject("age",30);
    mav.setViewName("/demo/view");
    return mav;
}

@RequestMapping(path = "/test02",method = RequestMethod.GET)
public String test02(Model model){
    
    
    model.addAttribute("name","hhhh");
    model.addAttribute("age",30);
    return "/demo/view";
}

The first is to put the model and view data into one object, and finally return them together, and the second is to put the model in the parameter and return the template file. From the code reading point of view, the second one is more concise and intuitive, and it is recommended to use it. Note that the first type uses addObject(), and the second type uses addAttribute(). The two cannot be mixed, and note that the first type returns data as ModelAndView, and the second type returns data as String. Of course, if the function parameter does not Objects carrying org.springframework.ui.Model will not be recognized as returning template files, but return strings.

Next, we will introduce how the json data should be transmitted through the Controller. It basically occurs in an asynchronous request, that is to say, each time the data is requested, the template data is returned, but the json data is returned, and the existing template file is updated by the browser, which will not cause the data volume of each request to be transmitted If it is too large, it will affect the user experience.

With the cooperation of the thymeleaf template engine, the Controller only adds the @RequestMapping annotation to transmit the template file by default. After adding @ResponseBody, we can transmit json data. Of course, the return data type cannot be String type, otherwise, it will only print, not Convert the data into json format and print it out. as follows:

@RequestMapping(path = "/emp",method = RequestMethod.GET)
@ResponseBody
public Map<String,Object> getEmp(){
    
    
    Map<String,Object> emp = new HashMap<>();
    emp.put("name","张三");
    emp.put("age",16);
    emp.put("code",778522);
    return emp;
}

Visit localhost:8888/yumuing/emp, return the data and print the data in the browser as follows:

{
    
    "code":778522,"name":"张三","age":16}

bug summary

The request parameter has been defined multiple times and cannot be accessed

Screenshot_20230203_212649

Cause:

  • Params have been defined in @RequestMapping, and params are defined in @RequestParam, resulting in an error.
  • If @RequestParam(xxx) is written before the parameter, and require = false is not added, then the front end must have the corresponding xxx name, otherwise, an error will occur.
  • When @RequestBody receives data, the front end cannot use GET to submit data, but use POST to submit it. Otherwise an error will also occur.
  • When accessing static files, the path is a relative path placed in the resource/static directory. For example, if the test.html file is in /resourse/static/html/test.html, the path is localhost:port number/html/test.html, unless A global url prefix is ​​configured.

The error effect is as follows:

access page display

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Feb 03 21:33:35 HKT 2023
There was an unexpected error (type=Bad Request, status=400).

console output

2023-02-03T21:33:35.418+08:00  INFO 24684 --- [nio-8888-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-02-03T21:33:35.418+08:00  INFO 24684 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-02-03T21:33:35.418+08:00  INFO 24684 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
2023-02-03T21:33:35.430+08:00  WARN 24684 --- [nio-8888-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.UnsatisfiedServletRequestParameterException: Parameter conditions "username, password" not met for actual request parameters: ]
 

solution:

  • The first one: delete the redundant definition in @RequestMapping.
  • The second type: either add require = false, or request to add the corresponding parameter, or the backend does not add the parameter
  • The third way: use Post request, or delete this annotation
  • The fourth type: just write the correct path

Note: System.out.printf() is console output, return, HttpServletResponse, etc. are all page output.

Could not find template file

The console reports an error:

Error resolving template template might not exist or might not be accessible;

solution:

  • Modify the configuration in the application.yml file to:

    Ensure that the html file can be read. Note that there is an English half-width "dot" in front of it. Set cache to not cache to ensure real-time modification and take effect in real time. The production environment is recommended for easy debugging. The deployment environment is changed to cache type. Set the file path, do not add a slash after /templates.

    spring:
      thymeleaf:
        suffix: .html
        encoding: utf-8
        mode: HTML5
        cache: false
        prefix: classpath:/template
    
  • Modify the access template path of the Controller function to a relative path, such as: /demo/view, remember that there is a slash at the front and no slash at the end, no need to write the suffix name, the default is html

The test code in this article is obtained from my blog Spring Controller Basic Understanding and Application

Ask for likes and forward

Guess you like

Origin blog.csdn.net/yumuing/article/details/128886528