在Spring MVC中获取请求方式参数的主要方式有@RequestParam,@PathVariable,@RequestBody,HttpServletRequest,@RequestHeader等方式,接下来我们分别对其请求获取参数的方式进行相关介绍和使用。
@RequestParam
用于获取请求参数,适用于GET和POST请求。例如:
@GetMapping("/example")
public String example(@RequestParam("paramName") String param) {
// 处理参数
return "result";
}
优点:
- 简单易用,适合获取简单的请求参数。
- 支持设置默认值和必填参数。
- 可以直接将请求参数映射到方法参数,代码简洁。
缺点:
- 只适用于GET和POST请求,无法处理复杂数据结构。
- 对于大量参数时,方法签名可能会变得冗长。
使用场景:
- 适合处理简单的表单提交或URL查询参数,例如搜索功能、过滤条件等。
@PathVariable
用于获取URL路径中的变量,通常用于RESTful风格的请求。例如:
@GetMapping("/example/{id}")
public String example(@PathVariable("id") Long id) {
// 处理id
return "result";
}
优点:
- 适合RESTful风格的API设计,能够清晰地表达资源的层次结构。
- URL中直接包含参数,易于理解和使用。
缺点:
- 只能用于URL路径中的参数,无法处理查询参数。
- URL结构需要设计得当,可能会影响API的灵活性。
使用场景:
- 适合RESTful API中的资源操作,例如获取特定用户信息(/users/{id})、删除某个资源等。
@RequestBody
用于获取请求体中的数据,通常用于POST请求,特别是当请求内容是JSON或XML时。例如:
@PostMapping("/example")
public String example(@RequestBody MyObject myObject) {
// 处理myObject
return "result";
}
优点:
- 可以直接将请求体中的复杂对象映射到Java对象,适合处理JSON或XML数据。
- 支持复杂数据结构,能够处理嵌套对象。
缺点:
- 需要确保请求体的格式正确,可能会导致解析错误。
- 不适用于GET请求,因为GET请求没有请求体。
使用场景:
- 适合处理POST、PUT等请求,尤其是需要提交复杂数据结构的场景,如创建用户、更新资源等。
HttpServletRequest
可以通过注入HttpServletRequest对象来获取请求的所有信息,包括参数、头信息等。例如:
@GetMapping("/example")
public String example(HttpServletRequest request) {
String param = request.getParameter("paramName");
// 处理参数
return "result";
}
优点:
- 提供了对请求的全面访问,包括参数、头信息、请求方法等。
- 灵活性高,可以根据需要获取各种信息。
缺点:
- 代码相对冗长,不够简洁。
- 需要手动解析参数,增加了出错的可能性。
使用场景:
- 适合需要访问请求的多个方面,或者在处理请求时需要动态获取参数的场景。
@RequestHeader
用于获取请求头中的参数。例如:
@GetMapping("/example")
public String example(@RequestHeader("Authorization") String authHeader) {
// 处理请求头
return "result";
}
优点:
- 可以方便地获取请求头中的信息,如认证信息、用户代理等。
- 代码简洁,易于理解。
缺点:
- 只适用于获取请求头中的参数,无法处理其他类型的请求数据。
- 对于不常用的请求头,可能会导致代码的可读性下降。
使用场景:
- 适合需要获取认证信息、跨域请求中的CORS头、或其他特定请求头的场景。
补充
@CookieValue
我们还可以通过 @CookieValue将cookie数据和控制器方法的形参创建映射关系从而将值进行获取
@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
@RequestMapping("/testParam")
public String testParam(HttpServletRequest request){
//只要我们在这里获取session,他就会对我们的所有操作绑定一个cookie,前提条件必须执行该方法
HttpSession session = request.getSession();
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("前端获取的用户名称:"+ username + ";密码" + password);
return "success";
}
/**
* @RequestHeader注解的作用是将请求头绑定到控制器方法的参数上
* 如果请求头没有传递,则会报错,如果请求头传递了值,则使用请求头的值
* 例如defaultValue = "123"
* @CookieValue注解的作用是将请求头绑定到控制器方法的参数上
*/
@RequestMapping("/testParam4")
public String testParam4(@RequestParam("username") String username, @RequestParam("password") String password,
@RequestHeader("referer") String referer,
@CookieValue("JSESSIONID") String sessionId){
System.out.println("username:"+ username + ";password:" + password);
System.out.println("referer:"+ referer);
System.out.println("sessionId:"+ sessionId);
return "success";
}
优点:
- 可以方便地获取客户端发送的 Cookie 值,适用于需要基于 Cookie 进行身份验证或状态管理的场景。
- 代码简洁,易于理解。
缺点:
- 只能获取 Cookie 中的值,无法处理其他类型的请求参数。
- 需要确保客户端正确设置了 Cookie,否则可能会导致获取失败。
使用场景:
- 适合需要从 Cookie 中获取信息的场景,例如用户登录状态、用户偏好设置等。
直接从前端传递实体类
可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值
<form th:action="@{/testpojo}" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" value="男">男<input type="radio"name="sex" value="女">女<br>
年龄:<input type="text" name="age"><br>
邮箱:<input type="text" name="email"><br>
<input type="submit">
</form>
@RequestMapping("/testpojo")
public String testPOJO(User user){
System.out.println(user);
return "success";
}
//最终结果-->User{id=null, username='张三', password='123', age=23, sex='男',email='123@qq.com'}
乱码问题解决
顺带完成一下我们在Tomcat中因为Tomcat版本问题导致的乱码问题,主要是关于Post的请求会导致乱码问题
tomcat 低于8的版本,我们进入server.xml文件,然后配置如下配置
<Connector port="8080" URIEncoding="UTF-8" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
解决请求参数的乱码问题,需要在web.xml中使用SpringMVC提供的编码过滤器,CharacterEncodingFilter。
<!--配置springMVC的编码过滤器-->
<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>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
顺带为了给初学者提供方便,我这里给出完整的web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<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>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
通常情况下,@RequestParam和@PathVariable用于简单的参数获取,@RequestBody用于复杂数据结构的处理,而HttpServletRequest和@RequestHeader则提供了更大的灵活性和控制力。根据项目的需求,合理选择合适的方式可以提高代码的可读性和维护性。
补充:
如果你IDEA的配置中全部配置成UTF-8,且你配置了post和get的编码集处理,还是输出中文乱码,请在Tomcat虚拟机配置处配置 -Dfile.encoding=UTF-8