获取请求参数
一、导读
-
web的流程:
① 匹配请求与控制方法
② 处理请求,获取请求参数
③ 调用service方法处理业务逻辑
④ 共享域对象
⑤ 返回视图对象,进行响应
-
回顾ServletAPI获取请求参数
Browser发送请求,由DispatcherServlet进行统一处理,通过几个中间组件后间接调用控制类及控制方法,因此DispatcherServlet内封装了很多的数据,当匹配的控制器方法内的参数为HttpServletRequest类型时,该形参就表示该请求
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>测试请求参数</title> </head> <body> <h1>测试请求参数页面</h1> <a th:href="@{/testServletAPI(username='admin',password='abc')}">测试ServletAPI</a> </body> </html>
java
@Controller public class ParamController { @RequestMapping("/testServletAPI") public String servletAPITest(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username = " + username); System.out.println("password = " + password); return "success"; } }
二、使用控制器方法参数获取请求参数
-
控制方法内的形参要和请求中的参数名保持一致
-
请求中如果有form表单发送的多个同名参数,则在控制器方法内的参数可以使用对应类型的数组格式进行接收
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>测试请求参数</title> </head> <body> <h1>测试请求参数页面</h1> <form th:action="@{/testParam}" method="post"> 用户名:<input type="text" name="username"/><br/> 密码:<input type="password" name="pwd" /><br/> 性别:<input type="radio" name="sex" value="男"/>男<input type="radio" name="sex" value="女"/>女<br/> 爱好:<input type="checkbox" name="hobby" value="乒乓"/>乒乓 <input type="checkbox" name="hobby" value="围棋"/>围棋 <input type="checkbox" name="hobby" value="机器人"/>机器人<br/> <input type="submit" value="测试控制器方法参数获取请求参数"/> </form> </body> </html>
java
@Controller public class ParamController { @RequestMapping("testParam") public String paramTest(String username,String pwd, String sex,String[] hobby) { System.out.println("username = " + username); System.out.println("Arrays.toString(hobby) = " + Arrays.toString(hobby)); return "success"; } }
三、@RequestParam
-
作用是将请求参数和控制器方法内的参数创建映射关系
-
@RequestParam共有三个属性
**value:**指定为形参赋值的请求参数的参数名
name:和value的作用一样,与value互为别名
**required:**设置是否必须传输此请求参数,
默认值为true,表示请求必须传输value所指定的而请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则报错400;
若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则标识的形参值为null;
**defaultValue:**无论requried属性值为true或false,当value所指定的请求参数没有传输时,则使用默认值为形参赋值。
-
代码示例
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>测试请求参数</title> </head> <body> <h1>测试请求参数页面</h1> <a th:href="@{/testRequestParam(username='admin',password='abc')}">测试RequestParam</a> </body> </html>
java
@Controller public class ParamController { @RequestMapping("/testRequestParam") public String requestParamTest( @RequestParam(value = "username",required = false,defaultValue = "MVC") String user_name, String password ) { System.out.println("user_name = " + user_name); System.out.println("pwd = " + password); return "success"; } }
四、@RequestHeader
-
将请求头信息和控制器方法内的参数创建映射关系
-
有三个属性值,和@RequestParam中的一样
-
代码测试
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>测试请求参数</title> </head> <body> <h1>测试请求参数页面</h1> <a th:href="@{/testRequestParam(username='admin',password='abc')}">测试RequestParam</a> </body> </html>
java
@RequestMapping("/testRequestParam") public String requestParamTest( @RequestParam(value = "username",required = false,defaultValue = "MVC") String user_name, @RequestHeader(value = "Host",required = false,defaultValue = "hehe") String host ) { System.out.println("host = " + host); return "success"; }
五、@CookieValue
-
将cookie数据和控制器方法内的参数创建映射关系
-
Cookie与Session,Cookie是客户端的会话技术,Session是服务端的会话技术。Session依赖与Cookie,故每当创建一个HttpSession时,就会创建一个Cookie
第一次发送请求时,Cookie是产生在响应报文中,后续的请求就都是在请求报文中
-
代码测试
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>测试请求参数</title> </head> <body> <h1>测试请求参数页面</h1> <a th:href="@{/testCookieValue}">测试CookieValue</a> </body> </html>
java
@Controller public class ParamController { @RequestMapping("/testCookieValue") public String cookieTest( HttpServletRequest request, @CookieValue(value = "JSESSIONID",required = false) String JSESSIONID ) { HttpSession session = request.getSession(); // 第一次请求时,JESSION的值为null,再次请求时,才会产生值。 System.out.println("JESSION = " + JSESSIONID); return "success"; } }
六、Pojo类获取请求参数
-
可以在控制器方法的形参位置设置一个实体类型的形参,该实体类中的属性与浏览器传输的请求参数名一一对应,那么请求参数就会为此实体类内的属性赋值
-
代码测试
html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>测试请求参数</title> </head> <body> <h1>测试请求参数页面</h1> <form th:action="@{/testPojoParam}" method="post"> 用户名:<input type="text" name="username"/><br/> 密码:<input type="password" name="pwd" /><br/> 性别:<input type="radio" name="sex" value="男"/>男<input type="radio" name="sex" value="女"/>女<br/> 爱好:<input type="checkbox" name="hobby" value="乒乓"/>乒乓 <input type="checkbox" name="hobby" value="围棋"/>围棋 <input type="checkbox" name="hobby" value="机器人"/>机器人<br/> <input type="submit" value="测试控制器方法参数获取请求参数"/> </form> </body> </html>
pojo
public class User { private String username; private String pwd; private String sex; private String[] hobby; // 省略了get/setf @Override public String toString() { return "User{" + "username='" + username + '\'' + ", pwd='" + pwd + '\'' + ", sex='" + sex + '\'' + ", hobby=" + Arrays.toString(hobby) + '}'; } }
controller
@Controller public class ParamController { @RequestMapping("/testPojoParam") public String pojoTest(User user) { System.out.println("user = " + user); return "success"; } }
七、web中获取请求参数的乱码问题
-
get请求的乱码问题
-
post请求的乱码问题
<?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"> <!-- 2.在过滤器内设置编码格式 解析 CharacterEncodingFilter 类的源码 package org.springframework.web.filter; public class CharacterEncodingFilter extends OncePerRequestFilter { // ① encoding:表示编码格式,但是注解为可以为空 @Nullable private String encoding; private boolean forceRequestEncoding; private boolean forceResponseEncoding; public CharacterEncodingFilter() { this.forceRequestEncoding = false; this.forceResponseEncoding = false; } protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { String encoding = this.getEncoding(); // ② 在xml内设置了encoding的值后,进入if内部 if (encoding != null) { /* ③ request的encoding还没有设置,故为空,满足if条件,将xml内设置 的encoding的值赋值给request的encoding */ if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) { request.setCharacterEncoding(encoding); } /* s 为了能使xml内设置的encoding的值赋值给response的encoding,故 要在xml将isForceResponseEncoding设置为true */ if (this.isForceResponseEncoding()) { response.setCharacterEncoding(encoding); } } filterChain.doFilter(request, response); } } --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!-- 2.1 设置参数encoding的值为UTF-8 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!-- 2.2 设置forceResponseEncoding参数的值为true --> <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> </web-app>