Spring MVC 提供了多种获取请求参数的方式:
- 通过 HttpServletRequest 获取请求参数
- 通过控制器方法的形参获取请求参数
- 使用 @RequestParam 注解获取请求参数
- 通过实体类对象获取请求参数(推荐)
通过 HttpServletRequest 获取请求参数
我们可以在控制器方法中设置一个 HttpServletRequest 类型的形参,Spring MVC 会自动将请求中携带的参数封装到 HttpServletRequest 形参中,然后我们就可以通过 HttpServletRequest 提供的 getParameter() 方法获取所需的请求参数了。
通过形参获取请求参数
我们可以在 Controller 的控制器方法中设置与请求参数同名的形参,以获取请求中携带的参数。当浏览器发送的请求匹配到这个控制器方法时,Spring MVC 会自动将请求参数赋值给相应的方法形参。
-
必须保证参数名一致
我们必须保证控制器方法的形参名称与请求中携带参数的名称完全一致(区分大小写),否则控制器方法接收到的请求参数值会是 null。
如果由于一些特殊原因,实在无法保证参数名严格一致,我们还可以通过 @RequestParam 注解来解决。 -
无视数据类型
这种方式是无视参数的数据类型的,我们可以在控制器方法中使用 String 字符串类型的形参接收所有的请求参数,也可以根据实际情况在控制器方法中使用对应数据类型的参数来接收请求参数,而无须自行进行数据类型转换。 -
不适用于请求参数过多的请求
当请求中携带的参数过多时,如果我们还使用这种方式来获取请求参数,那就需要我们在控制器方法中设置大量的形参,这会让使代码变得十分臃肿,不易维护。 -
同名请求参数的处理方式
当请求中包含多个同名的请求参数时,我们可以通过以下 2 种类型的形参来获取请求参数。
形参的数据类型 | 获取到的请求参数值 | 举例 |
---|---|---|
String(字符串) | 所有同名请求参数的值通过逗号(“,”)拼接在一起。 | “true,false,true” |
数组 | 由所有同名请求参数值组成的数组。 | 该数组通常为 String(字符串)类型的,如果所有同名请求参数值都符合同一个数据类型的规范,我们还可以使用与之对应的数据类型的数组进行接收。例如,如果所有同名请求参数的取值都是 true 或 false,那么我们就可以在控制器方法中使用 Boolean 类型数组的形参进行接收. |
实例
创建FormalParamController类“
package com.example.firstdemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class FormalParamController {
/**
* 跳转到 user.html
* @return
*/
@RequestMapping("/user")
public String sayHello() {
return "user";
}
/**
* 通过形参获取请求参数
* @param userId
* @param userName
* @param password
* @return
*/
@RequestMapping("/getFormalParam")
public String getFormalParam(String userId, String userName, String password) {
System.out.println("userId:" + userId);
System.out.println("userName:" + userName);
System.out.println("password:" + password);
return "success";
}
}
在WEB-INF/template目录中创建以恶个user.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>C语言中文网</title>
</head>
<body>
<form th:action="@{/getFormalParam}" method="post">
<table style="margin: auto">
<tr>
<td>用户 ID:</td>
<td><input type="text" name="userId" required><br></td>
</tr>
<tr>
<td>用户名:</td>
<td><input type="text" name="userName" required><br></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" required><br></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit"></td>
</tr>
</table>
</form>
</body>
</html>
使用@RequestParam注解获取
我们可以在控制器方法中通过 @RequestParam 注解,在请求参数与控制器方法的形参之间建立起映射关系,将它们绑定起来。这样即使请求参数与控制器方法中的形参名称不一致,我们也能获取到对应的请求参数值。
实例
创建RequestParamController类
package com.example.firstdemo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class RequestController {
@RequestMapping("/testRequestParam")
public String testRequestParamTest(@RequestParam("name") String username,@RequestParam("pass") String password){
System.out.println("username:"+username+"\tpassword:"+password);
return "success";
}
}
测试地址:http://localhost:8080/first-demo/testRequestParam?name=UserName&pass=123456
通过实体类对象获取(推荐)
我们可以在 Controller 控制器方法的形参中设置一个实体类形参,如果请求参数的参数名与实体类中的属性名一致,那么 Spring MVC 会自动将请求参数封装到该实体类对象中。此时我们就可以通过该实体类对象获取所需的请求参数了。
注:我们推荐大家使用实体类对象来获取请求参数,这也是最常用的请求参数的方式之一,它能够有效地解决“控制器方法形参不适用于请求参数过多的请求”问题。
实例
在entities目录下创建User实体类:
package com.example.firstdemo.entities;
public class User {
private String userId;
private String userName;
private Integer password;
public User() {
}
public User(String userId, String userName, Integer password) {
this.userId = userId;
this.userName = userName;
this.password = password;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getPassword() {
return password;
}
public void setPassword(Integer password) {
this.password = password;
}
@Override
public String toString() {
return "User:["+"\tUserId:"+userId+"\tUserName:"+userName+"\tPassword:"+password+"]";
}
}
在controller目录下创建UserController:
package com.example.firstdemo.controller;
import com.example.firstdemo.entities.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping("/user")
public String sayHello() {
return "user";
}
/**
* 通过实体类获取请求参数
*
* @param user
* @return
*/
@RequestMapping("/getUser")
public String getUser(User user) {
System.out.println("userId:" + user.getUserId()+
"\tuserName:" + user.getUserName()+
"\tpassword:" + user.getPassword());
return "success";
}
}
在WEB-INF/ttemplates目录下创建user2.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<form th:action="@{/getUser}" method="post">
<table style="margin: auto">
<tr>
<td>用户 ID:</td>
<td><input type="text" name="userId" required><br></td>
</tr>
<tr>
<td>用户名:</td>
<td><input type="text" name="userName" required><br></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" required><br></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit"></td>
</tr>
</table>
</form>
</body>
</html>
测试:http://localhost:8080/first_demo/user
解决获取请求参数的乱码问题
当我们在 post 请求中传递的参数为中文时,控制器方法获取到的参数值会出现乱码的情况。
Spring MVC 默认提供了一个过滤器 CharacterEncodingFilter,我们只需要在 web.xml 中对该 Filter 进行简单的配置,即可解决请求和响应中的中文乱码问题。
<!--请求和响应的字符串过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--设置请求的编码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--设置响应的编码,这里我们可以省略-->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>