2, Binding of request parameters
2.1 preparation
In this section, we will use classes on servlet requests such as HttpServletRequest and HttpServletResponse. Servlet API package dependency needs to be introduced. It is necessary to note that the java EE specification was renamed Jakarta EE in 2018. Accordingly, the package name we used before was renamed jakarta.xx from javax.xx. In order to adapt to the new standard, we updated the latest version of spring 5.3.13 and introduced Jakarta. Servlet API.
<properties> <spring.version>5.3.13</spring.version> <thymeleaf.version>3.0.12.RELEASE</thymeleaf.version> <servlet-api.version>4.0.4</servlet-api.version> <annotation-api.version>1.3.5</annotation-api.version> </properties> <dependencies> <!--servlet api--> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>${servlet-api.version}</version> <scope>provided</scope> </dependency> <!-- Spring rely on --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- thymeleaf--> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>${thymeleaf.version}</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>${thymeleaf.version}</version> </dependency> <!--annotation--> <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> <version>${annotation-api.version}</version> </dependency> </dependencies>
-
Possible problems
-
@The Resource annotation cannot be import ed, or the injection is empty
Add the dependency of the annotation API and confirm the version number
-
Unable to start Tomcat org.apache.catalina.LifecycleException: subcontainer startup failed
Solution: confirm whether there are multiple spring web components of different versions in the deployed war package, and clean up the redundant jar package.
https://blog.csdn.net/AIMINdeCSDN/article/details/103590010
-
2.2 three methods of parameter binding
2.2.1 obtaining parameters through servlet API
We can add parameters HttpServletRequest and HttpServletResponse to the controller method, and then obtain the request parameters through the getParameter() method. The example code is as follows:
- Controller layer
Create a GET request / user with QueryParam parameter id and request id
GET /user?id=00112233
@Controller public class UserController { @Resource private UserService userService; @RequestMapping(value = "/user") @ResponseBody public String getUser(HttpServletRequest request, HttpServletResponse response) { String id = request.getParameter("id"); return userService.getUserName(id); } }
- Service layer
Here, we use hashmap to simulate the dao layer query database operation. The user with query id 00112233 is "zhangsan"
@Service public class UserService { private final Map<String, String> userMap = new HashMap<String, String>(){{ put("00112233", "Zhang San"); put("00112234", "Yan Si"); }}; public String getUserName(String userId) { return userMap.get(userId); } }
We use postman to test the interface, and you can see
Let's briefly introduce the common methods
// 1. Get QueryParam parameter // Specifies the parameter value of the parameter name, and returns null if it does not exist request.getParameter(String paramter); // Get all parameters. If multiple parameters are connected with &, for ex amp le, id = 00112233 & name = Zhangsan request.getQueryString(); // 2. Get url path parameters // Get the exact match with the "URL pattern" in the Servlet request.getServletPath()
2.2.2 obtain by annotation (recommended)
Due to the use of spring MVC, parameters are generally obtained through annotations. Common annotations are as follows:
- @PathVariable get path parameters
- value: the name of the binding URL path parameter
- name: same as value
- requried: required parameter; the default value is true; required.
- @RequestParam get QueryParam parameter
- value: parameter name in binding request
- name: same as value
- requried: required parameter; the default value is true; required.
- defaultValue: the default value when the parameter is not transferred.
- @RequestBody gets the body request body parameters, which can be serialized into an object
Let's demonstrate this by modifying the User example above:
Add pojo object User
@Getter @Setter @ToString public class User { private String id; private String name; }
Controller layer three requests
- Query a user: GET /user?id=00112233
- Add multiple users: POST /users
- Delete a user: DELETE /user/{user_id}
@Controller public class UserController { @Resource private UserService userService; @RequestMapping(value = "/user") @ResponseBody public String getUser(@RequestParam(value = "id") String id) { return userService.getUserName(id); } @RequestMapping(value = "/users") @ResponseBody public String getUser(@RequestBody List<User> users) { System.out.println(users); return "success"; } @RequestMapping(value = "/user/{user_id}") @ResponseBody public String deleteUser(@PathVariable(value = "user_id") String userId) { System.out.println(userId); return "success"; } }
Because we use the post request and serialize the parameters into list < user > objects, we plan to use json for serialization and deserialization, so we introduce the json serialization dependency jackson
Introducing jackson dependency into pom.xml
<jackson.version>2.13.0</jackson.version> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency>
-
be careful
If the request discovery response code is 415, jackson may not be introduced, so the related serialization dependency must be introduced.
In order to test the above three interfaces, the requests are constructed as follows:
-
GET /user?id=00112233
-
POST /users
[ { "id": 11223344, "name": "Zhang San" }, { "id": 55667788, "name": "Li Si" } ]
-
DELETE /user/00112233
The test results using postman tool are as follows:
2.2.3 QueryParam parameter binding with the same name
springmvc provides a mechanism for binding QueryParam parameters with the same name. For QueryParam parameters, springmvc will automatically find parameters with the same name on the Controller method or properties with the same name on the entity class for binding. A simple example is as follows:
We modified the previous HelloController and added two interfaces as follows:
- Query the specified user name: GET /hello?userName=ZhangSan
- Query the specified user: get / Hello? Id = 00112233 & name = Zhangsan
@Controller public class HelloController { @RequestMapping("/hello") @ResponseBody public String helloUser(String userName) { return "Hi, " + userName; } @RequestMapping("/hello/user") @ResponseBody public String helloUser(User user) { System.out.println("hello world"); return "Hi, " + user.getName(); } }
In the above example, we annotated String userName with @ RequestParam. The test results are as follows:
In the first example, our request parameter is userName=ZhangSan, but without @ RequestParam annotation, ZhangSan can also be bound to userName; Similarly, the name value requested in the second example can also be bound to user.name. The following two examples show the binding mechanism with the same name:
You can see that the above userName and user.getName() values are null, and you can see the parameter binding mechanism of spring MVC with the same name. The value attributes of @ RquestParam and @ PathVariable solve the problem of inconsistent front and rear parameters. The parameters of the front end are generally underlined Kernel style (user_name), and the back end is generally small hump style (userName). Moreover, the parameter binding mechanism with the same name is not easy to maintain, so it is generally recommended to bind parameters through annotations.