Spring MVC中获取请求参数的方式
在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) {// 处理idreturn "result";
}
优点:
- 适合RESTful风格的API设计,能够清晰地表达资源的层次结构。
- URL中直接包含参数,易于理解和使用。
缺点:
- 只能用于URL路径中的参数,无法处理查询参数。
- URL结构需要设计得当,可能会影响API的灵活性。
使用场景:
- 适合RESTful API中的资源操作,例如获取特定用户信息(/users/{id})、删除某个资源等。
@RequestBody
用于获取请求体中的数据,通常用于POST请求,特别是当请求内容是JSON或XML时。例如:
@PostMapping("/example")
public String example(@RequestBody MyObject myObject) {// 处理myObjectreturn "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