Java充电社
专辑
博文
联系我
本人继续续收门徒,亲手指导
SpringMVC教程
-> 如何接受请求中的参数?
1、Helloword
2、@Controller、@RequestMapping
3、接口测试利器
4、如何接受请求中的参数?
5、@RequestBody接收Json格式数据
6、多文件上传
7、返回页面常见的5种方式
8、返回json格式数据 & 通用返回值设计
9、SpringMVC返回null是什么意思?
10、异步处理请求
11、如何集成静态资源?
12、拦截器怎么用?
13、统一异常处理
14、实战篇:通用返回值 & 异常处理设计
15、全注解的方式 & 原理解析
16、源码解析SpringMVC处理请求的流程
17、源码解析SpringMVC容器的启动过程
18、RequestBodyAdvice:对@ReuqestBody进行增强
19、ResponseBodyAdvice:对@ResponseBody进行增强
20、RESTful接口详解
21、接口调用利器RestTemplate
22、参数解析器HandlerMethodArgumentResolver解密
23、@RequestParam用法及原理详解
24、@RequestBody原理解密
25、@RequestHeader详解
26、@CookieValue详解
27、@RequestAttribute详解
28、@SessionAttribute详解
29、重定向和转向详解
30、Converter转换器详解
31、跨域问题详解
32、类容协商,颠覆你的认知
33、终章
34、CORS通信
35、浏览器安全策略 & CORS
36、Http中的Content-Type详解
上一篇:接口测试利器
下一篇:@RequestBody接收Json格式数据
<div style="display:none"></div> **大家好,我是路人,本文如果对你有帮助,点个在看,顺便忙转发一下,非常需要大家的支持,对java有兴趣的朋友欢迎加我微信itsoku交流。** ## 1、本文内容 Controler中的方法如何接收http请求过来的参数呢? 具体有哪些方式呢? 这些就是本文讨论的重点,本文主要围绕下面这些方式来介绍参数的接收 - 接收Servlet中的参数:HttpServletRequest、HttpServletResponse、HttpSession - 通过方法形参名称接收参数 - 通过@RequestParam接收参数 - 通过1个对象接收参数 - 通过多个对象接收参数 - 组合对象接收参数(对象中嵌套对象集合等等) - 通过@PathVariable接受url中的参数 ## 2、接收Servlet中的参数 比如我们想在方法中用到servlet中的对象:HttpServletRequest、HttpServletResponse、HttpSession,那么可以直接在方法的参数中声明这些对象即可,SpringMVC会自动将这些参数传递进来,用到哪个就声明哪个 ```java @RequestMapping("/receiveparam/test1.do") public ModelAndView test1(HttpServletRequest request, HttpServletResponse response, HttpSession session) { String name = request.getParameter("name"); String age = request.getParameter("age"); String msg = String.format("name:%s,age:%s", name, age); System.out.println(msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/WEB-INF/view/result.jsp"); modelAndView.addObject("msg", msg); return modelAndView; } ``` 对应的表单 ```html <form method="post" action="receiveparam/test1.do"> 姓名:<input name="name" value="路人"/> <br/> 年龄:<input name="age" value="30"/><br/> <input type="submit" value="提交"> </form> ``` ## 3、解决乱码问题 如果大家直接创建一个springmvc项目运行上面的案例,会发现name为中文的时候,会是乱码,这里需要在web.xml中添加下面配置,解决乱码问题 ```xml <!-- 添加CharacterEncodingFilter过滤器,这个类中会对request和response设置表名,解决参数乱码问题 --> <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> <!-- forceRequestEncoding为true,将设置request.setCharacterEncoding(encoding); --> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <!-- forceRequestEncoding为true,将设置response.setCharacterEncoding(encoding); --> <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> ``` 上面这段配置主要是添加了一个过滤器,这个过滤器户处理所有请求,相当于对所有请求会执行下面操作,而encoding我们设置的是UTF-8 ```java request.setCharacterEncoding(encoding); response.setCharacterEncoding(encoding); ``` ## 4、通过方法形参名称接收参数 表单 ```html <form method="post" action="receiveparam/test2.do"> 姓名:<input name="name" value="路人"/> <br/> 年龄:<input name="age" value="30"/><br/> <input type="submit" value="提交"> </form> ``` 控制器方法 ```java /** * springmvc调用这个方法之前,会根据方法参数名称,请求中获取参数的值,将其传入 * 过程: * 1、将request.getParameter("name")传递给方法的第1个参数name * 2、将Integer.valueOf(request.getParameter("age"))传递给方法的第2个参数age * * @param name * @param age * @return */ @RequestMapping("/receiveparam/test2.do") public ModelAndView test2(String name, Integer age) { String msg = String.format("name:%s,age:%s", name, age); System.out.println(msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/WEB-INF/view/result.jsp"); modelAndView.addObject("msg", msg); return modelAndView; } ``` 这种情况下,form表单中的参数名称和控制器方法中的参数名称一样,会按照名称一一对应进行赋值。 ## 5、通过@RequestParam接收参数 如果方法的参数名称和表单中的参数名称不一致的时候,可以通过 @RequestParam注解的value属性来指定表单中参数的名称。 比如下面表单的2个名称分别为:pname和page ```html <form method="post" action="receiveparam/test3.do"> 姓名:<input name="pname" value="路人"/> <br/> 年龄:<input name="page" value="30"/><br/> <input type="submit" value="提交"> </form> ``` 对应的方法如下,2个形参的参数名称分别为name和age,和表单中的名称不一致了,那么可以在方法的参数前面加上@RequestParam注解,注解的value为表单中元素的名称,参数name希望接受表单中pname的值,那么就需要在name这个参数前面加上@RequestParam("pname"),方法的第2个参数也一样,加上了@RequestParam("page") ```java /** * 如果方法的参数名称和表单中的参数名称不一致的时候,可以通过 @RequestParam注解的value属性来指定表单中参数的名称 * 比如:@RequestParam("pname") String name 接收 request.getParameter("pname") 的值 * 1、将request.getParameter("pname")传递给方法的第1个参数name * 2、将Integer.valueOf(request.getParameter("page"))传递给方法的第2个参数age * * @param name * @param age * @return */ @RequestMapping("/receiveparam/test3.do") public ModelAndView test3(@RequestParam("pname") String name, @RequestParam("page") Integer age) { String msg = String.format("name:%s,age:%s", name, age); System.out.println(msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/WEB-INF/view/result.jsp"); modelAndView.addObject("msg", msg); return modelAndView; } ``` `@RequestParam`用来将请求的参数和方法的参数进行绑定,这个注解还有几个属性,也比较常用,大家熟悉下 ```java public @interface RequestParam { //参数名称 @AliasFor("name") String value() default ""; //同value属性 @AliasFor("value") String name() default ""; //参数是不是必须的,默认为true,如果请求中没有这个参数,springmvc会报错 boolean required() default true; //默认值 String defaultValue() default ValueConstants.DEFAULT_NONE; } ``` ## 6、通过1个对象接收参数 通常方法不要超过5个,当http请求的参数多的时候,我们可以使用一个对象来接收,对象中的参数名称和http请求中的参数名称一致。 比如有下面表单 ```java <form method="post" action="receiveparam/test4.do"> 姓名:<input name="name" value="路人"/> <br/> 年龄:<input name="age" value="30"/><br/> <input type="submit" value="提交"> </form> ``` 我们可以定义一个UserInfoDto类来接收表单中的参数,这个类中有2个属性名称和上面表单中的属性名称一样。 ```java public class UserInfoDto { //姓名 private String name; //年龄 private Integer age; //省略了get、set方法 @Override public String toString() { return "UserModel{" + "name='" + name + '\'' + ", age=" + age + '}'; } } ``` 对应控制器的代码如下 ```java /** * 传递对象信息,参数比较多的时候,可以通过对象来传递信息 * 比如表单中2个参数(name、age) * 那么可以定义一个类 UserInfoDto(2个属性:name、age) 来接收表单提交的参数 * 控制器的方法参数为:(UserInfoDto userInfoDto) * springmvc调用这个方法的时候,会自动将UserModel创建好,并且将请求中的参数按名称设置到 UserInfoDto 的属性中,然后传递进来 * 相当于会执行下面代码: * UserInfoDto user = new UserInfoDto(); * user.setName(request.getParameter("name")); * user.setAge(Integer.valueOf(request.getParameter("age"))); * 然后将user对象传给当前方法的第一个参数 * * @param userInfoDto * @return */ @RequestMapping("/receiveparam/test4.do") public ModelAndView test4(UserInfoDto userInfoDto) { String msg = String.format("userDto:%s", userInfoDto); System.out.println(msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/WEB-INF/view/result.jsp"); modelAndView.addObject("msg", msg); return modelAndView; } ``` ## 7、通过多个对象接收参数 上面我们将form表单有一个对象来接收,实际上也可以用多个对象来接收。 表单如下 ```html <form method="post" action="receiveparam/test5.do"> 姓名:<input name="name" value="路人"/> <br/> 年龄:<input name="age" value="30"/><br/> 工作年限:<input name="workYears" value="10"/> <br/> 年龄:<input name="workAddress" value="上海市"/><br/> <input type="submit" value="提交"> </form> ``` 表单中有4个元素,我们用2个对象来接收,前面2个元素用UserInfoDto对象来接收,后面2个对象用WorkInfoDto对象来接收,我们需要定义2个类:UserInfoDto和WorkInfoDto ```java /** * 用户基本信息 */ public class UserInfoDto { //姓名 private String name; //年龄 private Integer age; //省略了get、set方法 @Override public String toString() { return "UserModel{" + "name='" + name + '\'' + ", age=" + age + '}'; } } /** * 工作基本信息 */ public class WorkInfoDto { //工作年限 private Integer workYears; //工作地点 private String workAddress; //省略了get、set方法 @Override public String toString() { return "WorkInfoDto{" + "workYears=" + workYears + ", workAddress='" + workAddress + '\'' + '}'; } } ``` 对应的控制器方法如下 ```java /** * 也可以用多个对象来接收 * 比如表单有4个元素[name,age,workYear,workAddress] * 其中请求的参数 name,age 赋值给UserInfoDto中的2个属性(name,age) * 另外2个参数 workYear,workAddress 赋值给WorkInfoDto中的2个属性(workYear,workAddress) * * @param userInfoDto * @param workInfoDto * @return */ @RequestMapping("/receiveparam/test5.do") public ModelAndView test5(UserInfoDto userInfoDto, WorkInfoDto workInfoDto) { String msg = String.format("userInfoDto:[%s], workInfoDto:[%s]", userInfoDto, workInfoDto); System.out.println(msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/WEB-INF/view/result.jsp"); modelAndView.addObject("msg", msg); return modelAndView; } ``` ## 8、组合对象接收参数(对象中嵌套对象、集合等等) 如下表单 ```java <form method="post" action="receiveparam/test6.do"> 姓名:<input name="userInfo.name" value="路人"/> <br/> 年龄:<input name="userInfo.age" value="30"/><br/> 工作年限:<input name="workInfo.workYears" value="10"/> <br/> 年龄:<input name="workInfo.workAddress" value="上海市"/><br/> 第1份工作公司:<input name="experienceInfos[0].company" value="百度"/> <br/> 第1份职位:<input name="experienceInfos[0].position" value="Java开发"/> <br/> 第2份工作公司:<input name="experienceInfos[1].company" value="阿里"/> <br/> 第2份职位:<input name="experienceInfos[1].position" value="Java资深开发"/> <br/> <input type="submit" value="提交"> </form> ``` 对应的控制器 ```java @RequestMapping("/receiveparam/test6.do") public ModelAndView test6(UserDto userDto) { String msg = String.format("userDto:[%s]", userDto); System.out.println(msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/WEB-INF/view/result.jsp"); modelAndView.addObject("msg", msg); return modelAndView; } ``` 重点要看方法参数`UserDto`这个类型的结构 ```java /** * 用户信息 */ public class UserDto { //个人基本信息 private UserInfoDto userInfo; //工作信息 private WorkInfoDto workInfo; //工作经验(0到n个) private List<ExperienceInfoDto> experienceInfos; //省略了get、set方法 @Override public String toString() { return "UserDto{" + "userInfo=" + userInfo + ", workInfo=" + workInfo + ", experienceInfos=" + experienceInfos + '}'; } } ``` UserDto类中有3个属性,2个对象,一个List集合,再来看看这3个类的代码 ```java /** * 用户基本信息 */ public class UserInfoDto { //姓名 private String name; //年龄 private Integer age; //省略了get、set方法 @Override public String toString() { return "UserModel{" + "name='" + name + '\'' + ", age=" + age + '}'; } } /** * 工作基本信息 */ public class WorkInfoDto { //工作年限 private Integer workYears; //工作地点 private String workAddress; //省略了get、set方法 @Override public String toString() { return "WorkInfoDto{" + "workYears=" + workYears + ", workAddress='" + workAddress + '\'' + '}'; } } /** * 工作经验 */ public class ExperienceInfoDto { //公司 private String company; //职位 private String position; //省略了get、set方法 @Override public String toString() { return "ExperienceInfoDto{" + "company='" + company + '\'' + ", position='" + position + '\'' + '}'; } } ``` 这里主要注意下集合数据的传递方式,表单中的名称需要有下标,从0开始,如下图: ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/215/043bf58e-0af4-45e6-8645-6e92934e2399.png) ## 9、通过@PathVariable接受url中的参数 有时候我们请求的url是下面这样的,有一部是动态的,也就是/userInfo/后面的部分,是userId,具体userId的值是多少我们不知道,此时我们怎么办? ```html /userInfo/1 /userInfo/2 /userInfo/3 /userInfo/4 ... /userInfo/{userId} ``` 这种情况下就可以用到动态url了,比如下面控制器的代码,注意`@RequestMapping`注解的value值为`/receiveparam/{v1}/{v2}.do`,被{}包裹的部分就是动态的部分,方法参数中可以通过`@PathVariabl`取到url动态部分的值。 ```java /** * 动态url:url中可以使用{变量名称}来表示动态的部分,{}包裹的部分可以替换为任意内容 * 比如:/receiveparam/{v1}/{v2}.do可以接受:/receiveparam/1/2.do、/receiveparam/路人/30.do 等等 * @PathVariable("变量名称")可以获取到url中动态部分的内容,将其赋值给方法的形参 * 比如当前方法收到了请求:/receiveparam/路人/30.do * 那么方法的第1个参数p1的值为:路人 * 第2个参数p2的职位30 * * @param p1 * @param p2 * @return */ @RequestMapping("/receiveparam/{v1}/{v2}.do") public ModelAndView test7(@PathVariable("v1") String p1, @PathVariable("v2") String p2) { String msg = String.format("p1:[%s],p2:[%s]", p1, p2); System.out.println(msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/WEB-INF/view/result.jsp"); modelAndView.addObject("msg", msg); return modelAndView; } ``` ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/215/24f5515e-5c7c-498c-9c72-b23542f48d2a.png) 请求和值对应关系 | 请求url | 方法参数p1的值 | 方法参数p2的值 | | ------------------------ | -------------- | -------------- | | /receiveparam/路人/30.do | 路人 | 30 | | /receiveparam/1/2.do | 1 | 2 | 上面这些接受参数的方式可以组合,比如下面这样,同时有servlet对象和自定义对象 ```java @RequestMapping("/receiveparam/test8.do") public ModelAndView test8(HttpServletRequest request, HttpServletResponse response, UserDto userDto) ``` ## 10、案例代码及测试用例 ### 10.1、代码地址 ```html https://gitee.com/javacode2018/springmvc-series ``` 可以下载下来部署到tomcat中运行查看上面每个案例的结果。 ### 10.2、案例代码有两种运行方式 #### 10.2.1、方式1:浏览器中查看效果 1、将chat02-receiveparam模块部署到tomcat中,然后访问首页即可看到案例,如下图 ```html http://localhost:8080/chat02/ ``` ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/215/a80b47c7-17b1-4edf-9655-d62eccb6b3dc.png) #### 10.2.2、方式2:HTTP Client的方式查看效果 通过idea中的**HTTP Client**来运行测试用例,**HTTP Client**用法不知道的朋友,可以移步:[异常高效的接口测试利器HTTP Client](http://www.itsoku.com/course/6/214) 如下图,HTTP Client测试用例代码都在`chat02-receiveparam/src/test/resources/ReceiveParamController.http`中 ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/215/e826afea-3b26-4790-859f-c5e5b67a3717.png) **下篇文章将介绍json格式数据的接收及原理**。 <a style="display:none" target="_blank" href="https://mp.weixin.qq.com/s/_S1DD2JADnXvpexxaBwLLg" style="color:red; font-size:20px; font-weight:bold">继续收门徒,亲手带,月薪 4W 以下的可以来找我</a> ## 最新资料 1. <a href="https://mp.weixin.qq.com/s?__biz=MzkzOTI3Nzc0Mg==&mid=2247484964&idx=2&sn=c81bce2f26015ee0f9632ddc6c67df03&scene=21#wechat_redirect" target="_blank">尚硅谷 Java 学科全套教程(总 207.77GB)</a> 2. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484192&idx=1&sn=505f2faaa4cc911f553850667749bcbb&scene=21#wechat_redirect" target="_blank">2021 最新版 Java 微服务学习线路图 + 视频</a> 3. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484573&idx=1&sn=7f3d83892186c16c57bc0b99f03f1ffd&scene=21#wechat_redirect" target="_blank">阿里技术大佬整理的《Spring 学习笔记.pdf》</a> 4. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247484544&idx=2&sn=c1dfe907cfaa5b9ae8e66fc247ccbe84&scene=21#wechat_redirect" target="_blank">阿里大佬的《MySQL 学习笔记高清.pdf》</a> 5. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485167&idx=1&sn=48d75c8e93e748235a3547f34921dfb7&scene=21#wechat_redirect" target="_blank">2021 版 java 高并发常见面试题汇总.pdf</a> 6. <a href="https://mp.weixin.qq.com/s?__biz=MzkwOTAyMTY2NA==&mid=2247485664&idx=1&sn=435f9f515a8f881642820d7790ad20ce&scene=21#wechat_redirect" target="_blank">Idea 快捷键大全.pdf</a> ![](https://itsoku.oss-cn-hangzhou.aliyuncs.com/itsoku/blog/article/1/2883e86e-3eff-404a-8943-0066e5e2b454.png)
#custom-toc-container