美文网首页
【转载】SpringMVC系列第4篇:接受参数有多少种方式?

【转载】SpringMVC系列第4篇:接受参数有多少种方式?

作者: f7629e2bca1c | 来源:发表于2021-06-13 17:09 被阅读0次

原文

https://mp.weixin.qq.com/s/2iC6f-WWZKvx9DdvmFFTZA

公众号:路人甲java

1、本文内容

Controller 中的方法如何接收 http 请求过来的参数呢?

具体有哪些方式呢?

这些就是本文讨论的重点,本文主要围绕下面这些方式来介绍参数的接收

接收 Servlet 中的参数:HttpServletRequest、HttpServletResponse、HttpSession

通过方法形参名称接收参数

通过@RequestParam 接收参数

通过 1 个对象接收参数

通过多个对象接收参数

组合对象接收参数(对象中嵌套对象集合等等)

通过@PathVariable 接受 url 中的参数

2、接收 Servlet 中的参数

比如我们想在方法中用到 servlet 中的对象:HttpServletRequest、HttpServletResponse、HttpSession,那么可以直接在方法的参数中声明这些对象即可,SpringMVC 会自动将这些参数传递进来,用到哪个就声明哪个

@RequestMapping("/receiveparam/test1.do")

publicModelAndViewtest1(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 =newModelAndView();

modelAndView.setViewName("/WEB-INF/view/result.jsp");

modelAndView.addObject("msg", msg);

returnmodelAndView;

}

对应的表单

姓名:

年龄:

form>

3、解决乱码问题

如果大家直接创建一个 springmvc 项目运行上面的案例,会发现 name 为中文的时候,会是乱码,这里需要在 web.xml 中添加下面配置,解决乱码问题

characterEncodingFilterfilter-name>

org.springframework.web.filter.CharacterEncodingFilterfilter-class>

encodingparam-name>

UTF-8param-value>

init-param>

forceRequestEncodingparam-name>

trueparam-value>

init-param>

forceResponseEncodingparam-name>

trueparam-value>

init-param>

filter>

characterEncodingFilterfilter-name>

/*url-pattern>

filter-mapping>

上面这段配置主要是添加了一个过滤器,这个过滤器会处理所有请求,相当于对所有请求会执行下面操作,而 encoding 我们设置的是 UTF-8

request.setCharacterEncoding(encoding);

response.setCharacterEncoding(encoding);

4、通过方法形参名称接收参数

表单

姓名:

年龄:

form>

控制器方法

/**

* springmvc调用这个方法之前,会根据方法参数名称,请求中获取参数的值,将其传入

* 过程:

* 1、将request.getParameter("name")传递给方法的第1个参数name

* 2、将Integer.valueOf(request.getParameter("age"))传递给方法的第2个参数age

*

*@paramname

*@paramage

*@return

*/

@RequestMapping("/receiveparam/test2.do")

publicModelAndViewtest2(String name, Integer age){

String msg = String.format("name:%s,age:%s", name, age);

System.out.println(msg);

ModelAndView modelAndView =newModelAndView();

modelAndView.setViewName("/WEB-INF/view/result.jsp");

modelAndView.addObject("msg", msg);

returnmodelAndView;

}

这种情况下,form 表单中的参数名称和控制器方法中的参数名称一样,会按照名称一一对应进行赋值。

5、通过@RequestParam 接收参数

如果方法的参数名称和表单中的参数名称不一致的时候,可以通过 @RequestParam 注解的 value 属性来指定表单中参数的名称。

比如下面表单的 2 个名称分别为:pname 和 page

姓名:

年龄:

form>

对应的方法如下,2 个形参的参数名称分别为 name 和 age,和表单中的名称不一致了,那么可以在方法的参数前面加上@RequestParam 注解,注解的 value 为表单中元素的名称,参数 name 希望接受表单中 pname 的值,那么就需要在 name 这个参数前面加上@RequestParam("pname"),方法的第 2 个参数也一样,加上了@RequestParam("page")

/**

* 如果方法的参数名称和表单中的参数名称不一致的时候,可以通过@RequestParam注解的value属性来指定表单中参数的名称

* 比如:@RequestParam("pname") String name 接收 request.getParameter("pname") 的值

* 1、将request.getParameter("pname")传递给方法的第1个参数name

* 2、将Integer.valueOf(request.getParameter("page"))传递给方法的第2个参数age

*

*@paramname

*@paramage

*@return

*/

@RequestMapping("/receiveparam/test3.do")

publicModelAndViewtest3(@RequestParam("pname")String name,

@RequestParam("page")Integer age)

{

String msg = String.format("name:%s,age:%s", name, age);

System.out.println(msg);

ModelAndView modelAndView =newModelAndView();

modelAndView.setViewName("/WEB-INF/view/result.jsp");

modelAndView.addObject("msg", msg);

returnmodelAndView;

}

@RequestParam用来将请求的参数和方法的参数进行绑定,这个注解还有几个属性,也比较常用,大家熟悉下

public@interfaceRequestParam {

//参数名称

@AliasFor("name")

Stringvalue()default"";

//同value属性

@AliasFor("value")

Stringname()default"";

//参数是不是必须的,默认为true,如果请求中没有这个参数,springmvc会报错

booleanrequired()defaulttrue;

//默认值

StringdefaultValue()defaultValueConstants.DEFAULT_NONE;

}

6、通过 1 个对象接收参数

通常方法不要超过 5 个,当 http 请求的参数多的时候,我们可以使用一个对象来接收,对象中的参数名称和 http 请求中的参数名称一致。

比如有下面表单

姓名:"name" value="路人"/>

年龄:"age" value="30"/>

我们可以定义一个 UserInfoDto 类来接收表单中的参数,这个类中有 2 个属性名称和上面表单中的属性名称一样。

publicclassUserInfoDto{

//姓名

privateString name;

//年龄

privateInteger age;

//省略了get、set方法

@Override

publicStringtoString(){

return"UserModel{"+

"name='"+ name +'\''+

", age="+ age +

'}';

}

}

对应控制器的代码如下

/**

* 传递对象信息,参数比较多的时候,可以通过对象来传递信息

* 比如表单中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对象传给当前方法的第一个参数

*

*@paramuserInfoDto

*@return

*/

@RequestMapping("/receiveparam/test4.do")

publicModelAndViewtest4(UserInfoDto userInfoDto){

String msg = String.format("userDto:%s", userInfoDto);

System.out.println(msg);

ModelAndView modelAndView =newModelAndView();

modelAndView.setViewName("/WEB-INF/view/result.jsp");

modelAndView.addObject("msg", msg);

returnmodelAndView;

}

7、通过多个对象接收参数

上面我们将 form 表单有一个对象来接收,实际上也可以用多个对象来接收。

表单如下

姓名:

年龄:

工作年限:

年龄:

form>

表单中有 4 个元素,我们用 2 个对象来接收,前面 2 个元素用 UserInfoDto 对象来接收,后面 2 个对象用 WorkInfoDto 对象来接收,我们需要定义 2 个类:UserInfoDto 和 WorkInfoDto

/**

* 用户基本信息

*/

publicclassUserInfoDto{

//姓名

privateString name;

//年龄

privateInteger age;

//省略了get、set方法

@Override

publicStringtoString(){

return"UserModel{"+

"name='"+ name +'\''+

", age="+ age +

'}';

}

}

/**

* 工作基本信息

*/

publicclassWorkInfoDto{

//工作年限

privateInteger workYears;

//工作地点

privateString workAddress;

//省略了get、set方法

@Override

publicStringtoString(){

return"WorkInfoDto{"+

"workYears="+ workYears +

", workAddress='"+ workAddress +'\''+

'}';

}

}

对应的控制器方法如下

/**

* 也可以用多个对象来接收

* 比如表单有4个元素[name,age,workYear,workAddress]

* 其中请求的参数 name,age 赋值给UserInfoDto中的2个属性(name,age)

* 另外2个参数 workYear,workAddress 赋值给WorkInfoDto中的2个属性(workYear,workAddress)

*

*@paramuserInfoDto

*@paramworkInfoDto

*@return

*/

@RequestMapping("/receiveparam/test5.do")

publicModelAndViewtest5(UserInfoDto userInfoDto, WorkInfoDto workInfoDto){

String msg = String.format("userInfoDto:[%s], workInfoDto:[%s]", userInfoDto, workInfoDto);

System.out.println(msg);

ModelAndView modelAndView =newModelAndView();

modelAndView.setViewName("/WEB-INF/view/result.jsp");

modelAndView.addObject("msg", msg);

returnmodelAndView;

}

8、组合对象接收参数(对象中嵌套对象、集合等等)

如下表单

姓名:"userInfo.name" value="路人"/>

年龄:"userInfo.age" value="30"/>

工作年限:"workInfo.workYears" value="10"/>

年龄:"workInfo.workAddress" value="上海市"/>

第1份工作公司:

第1份职位:

第2份工作公司:

第2份职位:

对应的控制器

@RequestMapping("/receiveparam/test6.do")

publicModelAndViewtest6(UserDto userDto){

String msg = String.format("userDto:[%s]", userDto);

System.out.println(msg);

ModelAndView modelAndView =newModelAndView();

modelAndView.setViewName("/WEB-INF/view/result.jsp");

modelAndView.addObject("msg", msg);

returnmodelAndView;

}

重点要看方法参数UserDto这个类型的结构

/**

* 用户信息

*/

publicclassUserDto{

//个人基本信息

privateUserInfoDto userInfo;

//工作信息

privateWorkInfoDto workInfo;

//工作经验(0到n个)

privateListexperienceInfos;

//省略了get、set方法

@Override

publicStringtoString(){

return"UserDto{"+

"userInfo="+ userInfo +

", workInfo="+ workInfo +

", experienceInfos="+ experienceInfos +

'}';

}

}

UserDto 类中有 3 个属性,2 个对象,一个 List 集合,再来看看这 3 个类的代码

/**

* 用户基本信息

*/

publicclassUserInfoDto{

//姓名

privateString name;

//年龄

privateInteger age;

//省略了get、set方法

@Override

publicStringtoString(){

return"UserModel{"+

"name='"+ name +'\''+

", age="+ age +

'}';

}

}

/**

* 工作基本信息

*/

publicclassWorkInfoDto{

//工作年限

privateInteger workYears;

//工作地点

privateString workAddress;

//省略了get、set方法

@Override

publicStringtoString(){

return"WorkInfoDto{"+

"workYears="+ workYears +

", workAddress='"+ workAddress +'\''+

'}';

}

}

/**

* 工作经验

*/

publicclassExperienceInfoDto{

//公司

privateString company;

//职位

privateString position;

//省略了get、set方法

@Override

publicStringtoString(){

return"ExperienceInfoDto{"+

"company='"+ company +'\''+

", position='"+ position +'\''+

'}';

}

}

这里主要注意下集合数据的传递方式,表单中的名称需要有下标,从 0 开始,如下图:

9、通过@PathVariable 接受 url 中的参数

有时候我们请求的 url 是下面这样的,有一部是动态的,也就是/userInfo/后面的部分,是 userId,具体 userId 的值是多少我们不知道,此时我们怎么办?

/userInfo/1

/userInfo/2

/userInfo/3

/userInfo/4

...

/userInfo/{userId}

这种情况下就可以用到多态 url 了,比如下面控制器的代码,注意@RequestMapping注解的 value 值为/receiveparam/{v1}/{v2}.do,被{}包裹的部分就是动态的部分,方法参数中可以通过@PathVariabl取到 url 动态部分的值。

/**

* 动态url:url中可以使用{变量名称}来表示动态的部分,{}包裹的部分可以替换为任意内容

* 比如:/receiveparam/{v1}/{v2}.do可以接受:/receiveparam/1/2.do、/receiveparam/路人/30.do 等等

*@PathVariable("变量名称")可以获取到url中动态部分的内容,将其赋值给方法的形参

* 比如当前方法收到了请求:/receiveparam/路人/30.do

* 那么方法的第1个参数p1的值为:路人

* 第2个参数p2的职位30

*

*@paramp1

*@paramp2

*@return

*/

@RequestMapping("/receiveparam/{v1}/{v2}.do")

publicModelAndViewtest7(@PathVariable("v1")String p1, @PathVariable("v2")String p2){

String msg = String.format("p1:[%s],p2:[%s]", p1, p2);

System.out.println(msg);

ModelAndView modelAndView =newModelAndView();

modelAndView.setViewName("/WEB-INF/view/result.jsp");

modelAndView.addObject("msg", msg);

returnmodelAndView;

}

请求和值对应关系

请求 url方法参数 p1 的值方法参数 p2 的值

/receiveparam/路人/30.do路人30

/receiveparam/1/2.do12

上面这些接受参数的方式可以组合,比如下面这样,同时有 servlet 对象和自定义对象

@RequestMapping("/receiveparam/test8.do")

publicModelAndViewtest8(HttpServletRequest request, HttpServletResponse response, UserDto userDto)

10、案例代码及测试用例

10.1、代码地址

https://gitee.com/javacode2018/springmvc-series

可以下载下来部署到 tomcat 中运行查看上面每个案例的结果。

10.2、案例代码有两种运行方式

10.2.1、方式 1:浏览器中查看效果

将 chat02-receiveparam 模块部署到 tomcat 中,然后访问首页即可看到案例,如下图

http://localhost:8080/chat02/

相关文章

网友评论

      本文标题:【转载】SpringMVC系列第4篇:接受参数有多少种方式?

      本文链接:https://www.haomeiwen.com/subject/srjoeltx.html