文章目录
SpringMVC的参数绑定支持的数据类型基本数据类型和字符串类型JavaBean包装类Map类型List类型 POST请求参数中文乱码的解决方法自定义类型转换器(Date类型转换)在控制器中使用原生的ServletAPI对象实现请求转发与重定向前台表单提交的数据格式是形如username=zhangsansan&age=18
的, SpringMVC的参数绑定过程就是把表单提交的请求参数,作为控制器中方法的参数进行绑定。
SpringMVC的参数绑定支持的数据类型
基本数据类型和字符串类型
提交表单的name和参数的名称要相同才能接到参数
@Controller@RequestMapping(path="/springmvc")public class ParametersController {/*接收请求 SpringMVC参数绑定类型:基本数据类型和字符串类型提交表单的name和参数的名称要相同才能接到参数。<form action="/springmvc/sai">名字:<input type="text" name="name"><br/>年龄:<input type="text" name="age"><br/><button type="submit">提交</button></form>*/@RequestMapping(path="/sai")public String select(String name,Integer age) {System.out.println(name+" "+age);return "login";}}
JavaBean
页面表单name的值需要和后台接收的JavaBean对应的属性名字一致
<div><form action="/springmvc/bean">名字:<input type="text" name="name"><br/>年龄:<input type="text" name="age"><br/>地址:<input type="text" name="adress"><br/><button type="submit">提交</button></form></div>
public class User {private String name;private Integer age;private String adress;..........}
@Controller@RequestMapping(path="/springmvc")public class ParametersController {/*接收请求 SpringMVC参数绑定类型:JavaBean页面表单name的值需要和后台接收的JavaBean对应的属性名字一致*/@RequestMapping(path="/bean")public String addUser(User user) {System.out.println(user);//User{name='周哈哈', age=23, adress='中国'}return "login";}}
包装类
// 包装类public class SuperUser {private String name;private Integer age;//引用属性private IDCard idCard;//引用属性(集合属性)private List<Account> accounts;...}public class IDCard {private String number;private String address;.......}public class Account {private String id;private Double money;....}
SpringMVC参数绑定类型:包装类 一对一
JavaBean有引用属性,页面表单则写 引用属性名.引用属性自身对应属性名
<div><form action="/springmvc/beanvo">名字:<input type="text" name="name"><br/>年龄:<input type="text" name="age"><br/>身份证号:<input type="text" name="idCard.number"><br/>住址:<input type="text" name="idCard.address"><br/><button type="submit">提交</button></form></div>
SpringMVC参数绑定类型:包装类 一对多
JavaBean有集合属性,则页面编写方式:该集合属性名[0].属性
<div><form action="/springmvc/beanvo">名字:<input type="text" name="name"><br/>年龄:<input type="text" name="age"><br/>身份证号:<input type="text" name="idCard.number"><br/>住址:<input type="text" name="idCard.address"><br/><div>====账户一====</div>账户id:<input type="text" name="accounts[0].id"><br/>余额:<input type="text" name="mobiles[0].money"><br/><div>====账户二====</div>账户id:<input type="text" name="accounts[1].id"><br/>余额:<input type="text" name="mobiles[1].money"><br/><div>=====账户三=====</div>账户id:<input type="text" name="accounts[2].id"><br/>余额:<input type="text" name="mobiles[2].money"><br/><button type="submit">提交</button></form></div>
一对一
一对多
@Controller@RequestMapping(path="/springmvc")public class ParametersController {/*接收请求 SpringMVC参数绑定类型:包装类页面表单name的值需要和后台接收的JavaBean对应的属性名字一致如果JavaBean有引用属性,页面表单则写 引用属性名.引用属性自身对应属性名如果接收的JavaBean里存在List集合,则页面需要每次用下标来告诉程序是第几个。页面编写方式:该集合引用属性名[0].引用属性自身对应属性名*/@RequestMapping(path="/beanvo")public String addSuperUser(SuperUser superUser) {System.out.println(superUser);//包装类 一对一 输出:SuperUser{name='周哈哈', age=23, idCard=IDCard{number='11111', address='江西'}, accounts=null} 表单没有accounts的相关提交参数,故accounts=null//包装类 一对多 输出:SuperUser{name='周哈哈', age=23, idCard=IDCard{number='11111', address='江西'}, accounts=[Account{id='aaa', money=10000.0}, Account{id='bbb', money=100000.0}, Account{id=' ccc', money=1111111.0}]}return "login";}}
Map类型
http://localhost:8080/springmvc/map?name=张三三&age=18
@Controller@RequestMapping(path="/springmvc")public class ParametersController {/*接收请求 SpringMVC参数绑定类型:Map类型需要加上@RequestParam注解接收Map数据*/@RequestMapping(path ="/map")public String addMap(@RequestParam Map<String,String> map){System.out.println(map);//{name=张三三, age=18}return "login";}}
List类型
<div><form action="/springmvc/list"><table><tr><td>选择</td><td>型号</td><td>价格</td></tr><tr><td><input type="checkbox" value="1" name="ids" /></td><td>华为Mate Xs</td><td>16999</td></tr><tr><td><input type="checkbox" value="2" name="ids" /></td><td>iPhone 11 </td><td>9599</td></tr></table><button type="submit">提交</button></form></div>
http://localhost:8080/springmvc/list?ids=1&ids=2
@Controller@RequestMapping(path="/springmvc")public class ParametersController {/*接收请求 SpringMVC参数绑定类型:List类型需要加上@RequestParam注解接收List类型*/@RequestMapping(value = "/list")public String addList(@RequestParam List<Integer> ids){System.out.println(ids);//[1, 2]return "login";}}
POST请求参数中文乱码的解决方法
以上用的都是GET请求回避了POST请求中文乱码问题
以JavaBean参数绑定为例:以post请求方式提交
<div><form action="/springmvc/bean" method="post">名字:<input type="text" name="name"><br/>年龄:<input type="text" name="age"><br/>地址:<input type="text" name="adress"><br/><button type="submit">提交</button></form></div>
@Controller@RequestMapping(path="/springmvc")public class ParametersController {/*接收请求 SpringMVC参数绑定类型:JavaBean页面表单name的值需要和后台接收的JavaBean对应的属性名字一致*/@RequestMapping(path="/bean")public String addUser(User user) {System.out.println(user);return "login";}}
控制台输出:
回顾:Filter(过滤器)
请求参数POST请求中文乱码的解决方法: 在web.xml中配置Spring提供的过滤器类
<!--配置过滤器,解决中文乱码的问题,注意:解决的是POST请求乱码问题CharacterEncodingFilter:用于做编码过滤,给指定请求的数据做编码--><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></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
自定义类型转换器(Date类型转换)
以上表单提交的所有数据类型都是字符串类型,不过后台方法入参却有定义为Integer类型的,这是因为Spring框架内部会默认进行数据类型转换。
而Date类型,由于开发需求不同,Spring框架并没有自动帮我们实现转换,需要自己转换。
不配置自定义类型转换器的情况下:
前端表单
<div><form action="/springmvc/bean" method="post">名字:<input type="text" name="name"><br/>年龄:<input type="text" name="age"><br/>生日:<input type="date" name="birthday"><br/>地址:<input type="text" name="adress"><br/><button type="submit">提交</button></form></div>
User
public class User {private String name;private Integer age;private String adress;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birthday;.........}
ParametersController 控制器类
@Controller@RequestMapping(path="/springmvc")public class ParametersController {@RequestMapping(path="/bean")public String addUser(User user) {System.out.println(user);return "login";}}
提交表单:服务器返回到客户端的状态码400 ,语义有误或请求参数有误,当前请求无法被服务器理解。
解决方法:
①自定义类型转换器
创建一个类型转换器DataConverter 实现Converter的接口
public class DataConverter implements Converter<String, Date> {//将字符类型转成Date类型@Overridepublic Date convert(String s) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");try {//将String转Datereturn simpleDateFormat.parse(s);} catch (ParseException e) {throw new RuntimeException(e);}}}
注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<!-- 配置spring开启注解mvc的支持--><mvc:annotation-driven conversion-service="conversionService" /><!--注册自定义类型转换器 --><bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><!--需要加入的类型转换器--><property name="converters"><bean class="com.mycode.util.DataConverter" /></property></bean>
测试控制台输出日志信息
②使用注解解决类型转换的问题
在需要转换的Date类型上加上@DateTimeFormat
注解
public class User {private String name;private Integer age;private String adress;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birthday;.........}
在springmvc.xml配置文件中配置注解驱动
<!--注解驱动--><mvc:annotation-driven />
在控制器中使用原生的ServletAPI对象实现请求转发与重定向
回顾:请求的转发与重定向
在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象,然后实现请求转发与重定向
@Controller@RequestMapping(value = "/servlet")public class ServletApiTestController {//基于Servlet实现重定向@RequestMapping(value = "/redirect")public void redirect(HttpServletRequest request, HttpServletResponse response){try {response.sendRedirect("/qq_45615417");} catch (IOException e) {e.printStackTrace();}}//基于Servlet实现转发@RequestMapping(value = "/forward")public void forward(HttpServletRequest request, HttpServletResponse response){try {request.getRequestDispatcher("/index.jsp").forward(request,response);} catch (Exception e) {e.printStackTrace();}}}
SpringMVC表单请求参数的绑定 配置编码过滤器解决请求参数中文乱码问题 自定义类型转换器