参数绑定
参数绑定过程:从客户端请求key/value数据,经过参数绑定,将数据绑定到Controller方法的形参上
springmvc中,接收页面提交的数据是通过方法的形参来接收的,而不是在Controller类定义成员变量接收
处理器适配器调用springmvc提供的参数绑定组件将key/value数据转成Controller方法形参
参数绑定组件:springmvc早期版本使用PropertyEditor(只能将字符串转换成java对象),后期使用convert(进行任意类型转换)
springmvc提供了很多convert(转换器),在特殊情况下需要自定义convert,如对日期数据绑定
默认支持的绑定类型:
HttpServletRequest,HttpServletResponse,HttpSession,ModelMap/Model(model是一个接口,modelMap是一个实现类),简单类型
Model/ModelMap作用:将model数据填充到request域
简单类型绑定
1.代码:
@RequestMapping("/query.action")
public ModelAndView query(Integer id) throws Exception{
url:http://localhost:8080/springmvc/query.action?id=5
此方法请求数据的key需要与Controller方法形参的名称一致。
2.通过@RequestParam注解对简单类型绑定
//@RequestParam指定request传入参数名与形参进行绑定
//通过required属性设值参数是否必须要传入
//defaultValue设置默认值,若参数没有传入使用默认值绑定形参
@RequestMapping("/query.action")
public ModelAndView query(@RequestParam(value="id",required=false,defaultValue="4" ) Integer i,@RequestParam(value="name") String username) throws Exception{
pojo参数绑定
@RequestMapping("/query.action")
public ModelAndView query( Integer id, Items items) throws Exception{
请求参数会自动绑定到与请求参数key相同的pojo形参属性名称上,pojo绑定和简单类型绑定互不影响
包装类型pojo参数绑定
在页面传入请求参数的时候使用 “自定义属性.属性名”,会自动绑定到包装类型的自定义参数上。
如:包装类型User中有Custom属性 ,请求参数名Custom.name,将会绑定到User的Custom属性中
validation校验
需要导入的jar包:
hibernate-validator-5.0.1.Final.jar
jboss-logging-3.1.0.CR2.jar
validation-api-1.1.0.Final.jar
classmate-0.8.0.jar
注意:hibernate-validator5.0以上版本不兼容validation-api-1.0版本,会出现ClassNotFound错误提示
校验器配置:
<!-- 配置校验器 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 注入hibernate校验器 -->
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
<!-- 校验错误信息配置文件,若不指定默认使用Classpath下的ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource"></property>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 资源文件名 -->
<property name="basenames">
<list>
<value>classpath:CustomValidationMessages</value>
</list>
</property>
<!-- 配置文件编码格式 -->
<property name="fileEncodings" value="utf-8"></property>
<!-- 配置资源文件内容缓存时间,单位秒 -->
<property name="cacheSeconds" value="120"></property>
</bean>
Controller类:
@RequestMapping("/query.action")
//在需要校验的pojo前加@Validated,在pojo后加BindingResult bindingResult接收校验出错信息
//@Validated和BingdingResult配对出现
public ModelAndView query( Integer id, Date date, @Validated Items items2, BindingResult bindingResult) throws Exception{
//打印错误信息
if(bindingResult.hasErrors()) {
List<ObjectError> allError = bindingResult.getAllErrors();
for(ObjectError error : allError) {
System.out.println(error.getDefaultMessage());
}
}
需要校验的属性:
public class Items {
@Size(min=1, max=3, message="{Items.name.length.errow}")
private String name;
@NotNull(message="{Items.id.isNull.errow}")
private int id;
错误信息CustomValidationMessages.properties文件:
Items.name.length.errow=请输入1至4个字符
Items.id.isNull.errow=id不能为空
分组校验
需求:在pojo中定义校验规则,而pojo是被多个Controller共用,当不同的Controller方法对同一个pojo进行校验,但是每个Controller需要不同的校验
解决办法:定义多个校验分组(一个接口),每个Contoller方法实现不同的校验分组
public interface ValidGroup1 {}
public interface ValidGroup2 {}
在校验规则中添加分组,一个属性可定义多个分组
public class Items {
@Size(min=1, max=3, message="{Items.name.length.errow}",groups={ValidGroup1.class})
@NotNull(message="{Items.name.isNull.error}",groups={ValidGroup1.class})
private String name;
@NotNull(message="{Items.id.isNull.errow}",groups={ValidGroup2.class})
private int id;
在Controller方法中指定分组校验
@RequestMapping("/query.action")
//value={ValidGroup1.class}指定只用这个分组的校验
public ModelAndView query( Integer id, @Validated(value={ValidGroup1.class}) Items items2, BindingResult bindingResult) throws Exception{
if(bindingResult.hasErrors()) {
List<ObjectError> allError = bindingResult.getAllErrors();
for(ObjectError error : allError) {
System.out.println(error.getDefaultMessage());
}
}
数据回显
提交后若出现错误将填写的信息回显给请求页面
1.spring默认对pojo数据进行回显
pojo数据传入Controller方法后,springmvc会自动将pojo数据放入request域,key等于pojo类名(首字母小写)
2.使用@ModelAttribute指定pojo回显到页面在request域中的key
@RequestMapping("/query.action")
//@ModelAttribute可以指定pojo回显页面在request域中的key
public ModelAndView query( Integer id, Date date, @ModelAttribute("items") @Validated(value={ValidGroup1.class}) Items items2, BindingResult bindingResult) throws Exception{
3.@ModelAttribute还可以将方法的返回值传到页面
在方法上面添加@ModelAttribute标签可以指定方法返回值在request域的key
4.可以使用简单方法model.addAttribute将数据添加到request域,而不用使用@MoelAttribute
public ModelAndView query( Model model,Integer id, @ModelAttribute("items") @Validated(value={ValidGroup1.class}) Items items2, BindingResult bindingResult) throws Exception{
model.addAttribute("items",items2);
5.对于简单类型的数据回显只能使用Model