本章案例基于上一章spring-mvc入门程序案例。
本章主要讲解Spring mvc获取请求参数的几种方式和类型
- 使用HttpServletRequest对象获取参数
- 简单数据类型绑定–获取简单数据参数
- @RequestParam映射
- 使用自动机制将参数绑定为POJO对象
- 自定义参数绑定
- 获取多个同类型参数绑定为数组
- 获取多个参数绑定List集合
1)使用HttpServletRequest对象获取参数
老方法,简单易懂,但是需要自己处理数据类型转化
例:
@Controller
public class HelloController {
//请求的url路径
@RequestMapping("/hello.do")
public ModelAndView hello(HttpServletRequest request){
System.out.println("Hello Controller!");
String param=request.getParameter("param");
System.out.println(param);
//返回视图
return new ModelAndView("jsp/hello");
}
}
注意:如果想获得Request对象只需要在Controller类方法的形参中添加一个参数即可。SpringMVC框架会自动把Request对象传递给方法。这就是SpringMVC框架默认支持的参数类型。
浏览器访问:
SpringMVC框架默认支持的参数类型
处理器形参中添加如下类型的参数,处理适配器会默认识别并进行赋值。
-
HttpServletRequest:通过request对象获取请求信息。
-
HttpServletResponse:通过response处理响应信息。
-
HttpSession:通过session对象得到session中存放的对象。
-
Model/ModelMap:ModelMap是Model接口的实现类(后面详细介绍)。
- 如果使用Model接口则可以不使用ModelAndView对象,Model对象可以向页面传递数据(model是框架给我们传递过来的对象,所以这个对象不需要我们返回),View对象则可以使用String返回值替代。不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。
2)简单数据类型绑定–获取简单数据参数
当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。**Spring会自动将表单参数注入到方法参数,不需要做任何处理。**从Request获取参数的方法可以进一步简化
例:
@RequestMapping("/demo.do")
public ModelAndView demo(Integer id,String name){
System.out.println(id+":"+name);
//返回视图
return new ModelAndView("jsp/hello");
}
SpringMVC框架支持的数据类型
-
整形:Integer、int
-
字符串:String
-
单精度:Float、float
-
双精度:Double、double
-
布尔型:Boolean、boolean
注意:参数类型推荐使用包装数据类型,因为基础数据类型不可以为null。
3)@RequestParam映射
当请求的参数名称和处理器形参名称不一致时可以使用@RequestParam注解映射,参数类型自动转换,但可能出现类型转换异常
例:
@RequestMapping("/demo01.do")
public ModelAndView demo01(
@RequestParam(value="id",defaultValue="1",required=true)Integer demoId
,String name){
System.out.println(demoId+":"+name);
//返回视图
return new ModelAndView("jsp/hello");
}
使用@RequestParam注解常用于处理简单类型的绑定。
-
value:参数名字,即入参的请求参数名字,如value=“id”表示请求的参数区中的名字为id的参数的值将传入。
-
required:是否必须,默认是false,为true时表示请求中一定要有相应的参数,否则将报如下错误:
-
defaultValue:默认值,表示如果请求中没有同名参数时的默认值。
形参名称为demoId,但是这里使用value=”id”限定请求的参数名为id,所以页面传递参数的名称必须为id。
这里通过required=true限定id参数为必须传递,如果不传递则报400错误,可以使用defaultvalue设置默认值,即使required=true也可以不传id参数值。
4)使用自动机制将参数绑定为POJO对象
如果提交的参数很多,或者提交的表单中的内容很多的时候可以使用pojo接收数据。要求pojo对象中的属性名和表单中input的name属性一致。 即pojo的属性名与请求参数名称一致。
先定义一个Demo类型
public class Demo{
private Integer id;
private String name;
//getter setter方法略写
}
form表单:
<form action="demo02.do" method="post">
编号id:<input type="text" name="id">
姓名name:<input type="text" name="name">
<input type="submit" value="提交">
</form>
Controller中参数绑定在POJO中:
@RequestMapping("/demo02.do")
public ModelAndView demo02(Demo demo){
System.out.println(demo);
//返回视图
return new ModelAndView("jsp/hello");
}
请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。注意:提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。
5)自定义参数绑定
提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。所以要真正解决这个需求,就必然要用到自定义参数绑定的内容。
由于日期数据有很多种格式,SpringMVC没办法把字符串转换成日期类型。所以需要自定义参数绑定。
前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。在SpringMVC中可以在处理器适配器上自定义Converter进行参数绑定。
自定义Converter
/**
* SpringMVC转换器
* Converter<S, T> S:source源数据类型,T:target目标数据类型
*/
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(source);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
配置Converter
<!-- 配置一个注解驱动,如果配置此标签,那么就可以不用配置处理器映射器和处理器适配器 -->
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 转换器的配置 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.oak.converter.DateConverter"/>
</set>
</property>
</bean>
Controller:
@RequestMapping("/demo03.do")
public ModelAndView demo03(Date time){
System.out.println(time);
//返回视图
return new ModelAndView("jsp/hello");
}
网页url:
测试,控制台输出:
Thu Nov 15 09:56:55 CST 2018
6)获取多个同类型参数绑定为数组
假设form表单中有如下input:
<form action="demo04.do" method="post">
编号id: <input type="text" name="id">
姓名name: <input type="text" name="name">
爱好interest:
游泳:<input type="checkbox" name="hobby" value="游泳">
打球:<input type="checkbox" name="hobby" value="打球">
打架:<input type="checkbox" name="hobby" value="啪啪">
<input type="submit" value="提交">
</form>
页面选中多个checkbox向Controller类的方法中传递。Controller类方法中可以用String[]接收,或者pojo的String[]属性接收。两种方式任选其一即可。
1)使用String [ ]接收
controller方法为:
@RequestMapping("/demo04.do")
public ModelAndView demo04(String [] hobby){
System.out.println(Arrays.toString(hobby));
//返回视图
return new ModelAndView("jsp/hello");
}
2)使用pojo的String [ ]属性接收。
在Demo中添加属性和getter setter方法
private String [] hobby;
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
Controller方法改为:
@RequestMapping("/demo04.do")
public ModelAndView demo04(Demo demo){
System.out.println(Arrays.toString(demo.getHobby()));
//返回视图
return new ModelAndView("jsp/hello");
}
分别测试即可
7)获取多个参数绑定List集合
需求:
假设现在已经访问查询所有的列表界面,要批量修改数据
案例
重新修改Demo为:
package com.oak.controller;
public class Demo {
private Integer id;
private String name;
//getter setter 构造 toString方法
}
新建一个QueryVo类,定义一个泛型为Demo的list集合作为属性:
public class QueryVo {
private List<Demo> demoList;
//getter setter 构造 toString方法
}
controller中定义查询所有demo的方法
@RequestMapping("/demoList.do")
public ModelAndView list(){
List<Demo> list=new ArrayList<Demo>();
list.add(new Demo(1,"张三"));
list.add(new Demo(2,"李四"));
list.add(new Demo(3,"王五"));
//返回视图
ModelAndView modelAndView=new ModelAndView("jsp/demo_list");
modelAndView.addObject("list",list);
return modelAndView;
}
使用input输入项的name属性必须是包装pojo的list属性+下标+元素属性。
可以使用< c:forEach >标签中的varStatus属性:
-
${status.index}:输出行号,从0开始。
-
${status.count}:输出行号,从1开始。
-
${status.current}:当前这次迭代的(集合中的)项。
-
${status.first}:判断当前项是否为集合中的第一项,返回值为true或false。
-
${status.last}:判断当前项是否为集合中的最后一项,返回值为true或false。
-
begin、end、step分别表示:起始序号,结束序号,跳跃步伐。
<form action="demoUpdate.do" method="post">
<c:forEach items="${list }" var="demo" varStatus="s">
编号id:<input type="text" name="demoList[${s.index }].id" value="${demo.id }" readonly="readonly"/>
姓名name:<input type="text" name="demoList[${s.index }].name" value="${demo.name }">
<br/>
</c:forEach>
<input type="submit" value="提交"/>
</form>
定义能接收数据的Controller方法:
@RequestMapping("/demoUpdate.do")
public ModelAndView update(QueryVo queryVo){
System.out.println(queryVo.getDemoList());
//返回视图
return new ModelAndView("jsp/hello");
}
注意:接收List类型的数据必须是pojo的属性,方法的形参为List类型无法正确接收到数据。
测试即可。