请求中的参数完成对hander的形参的绑定流程通俗的解释:
首先是前端发来请求(/user?id=1&name=zhangsan),所有的请求都会被dispathchservlet所拦截,他就会得到这个request对象,然后会根据request对象去找到对应的hander(handeler就是一个方法名)把这个request对象和hander方法交给databinder,由databinder完成将请求信息绑定到方法的入参(其实就是方法形参)中去。
databinder怎么绑定???
通过反射,根据handeler形参得到一个类的对象,然后通过类的对象得到他的class类对象,通过class对象拿到他的无参构造方法,然后通过无参构造方法new instence动态实例化一个对象(假设是一个object),然后通过键名id,找到这个id的setId的方法,往形参去set,根据键名name,找到这个name的setName方法,去完成形参set。。。在这个过程一定会遇到类型不匹配的问题,这时就要通过sonversionservice进行转换,把所有的string类型(这里类型并一定是自己想要的类型)转换为形参对应的数据类型(data,int,)。到这里通过类型转换已经拿到一个user类型的对象,但是这时属性不一定满足我的要求(比如我的 年龄不能超好100@DecimalMax(value = “100”),name不能为空@NotNull,满不满足email @Email命名规则等等的校验规则)这时就要用到hibernate-volidata框架定义的效规则进行效验,就是在pojo的属性上加标签实现。最后通过在形参列表中加入BindingResult,可以判断有没有不符合我们家的标签的,如果有就会报错。同时可以通过在形参加一个model域。这样把错误信息放到域里面就可以在jsp拿到错误信息具体内容。
数据绑定流程:
浏览器发送一个请求,通过在Action中定义一个成员变量来接收前台传进来的参数,而在springmvc中,接收页面提交的数据是通过方法形参来接收的。从客户端请求的key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上,然后就可以在controller中使用该参数了。
-
Spring MVC 主框架将 ServletRequest 对象及目标方 法的入参实例传递给 WebDataBinderFactory 实例,以创 建 DataBinder 实例对象
-
DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式 化工作。将 Servlet 中的请求信息填充到入参对象中(ConversionService就是一个完成数据类型转换的组件)
》源码中的类型转换: -
调用 Validator 组件对已经绑定了请求消息的入参对象 进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象(完成数据效验的组件)
-
Spring MVC 抽取 BindingResult 中的入参对象和校验 错误对象,将它们赋给处理方法的响应入参。
1,数据转换
举例:java.lang.String===>java.util.Date
使用注解:@DateTimeFormat(pattern = “yyyy-MM-dd”)
》自定义一个String转date的converter(debug看是否调用ConversionService 组件进行数据类型转换)
public class MyStringToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String s) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd-HH:mm:ss");
Date parse = null;
try {
parse = sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return parse;
}
}
》applicationContext.xml中的配置(为conwerters用set赋值)主要是通过配置绑定控制器中要转换的方法参数。
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.qf.converter.StringToDateConverter"></bean>
</set>
</property>
</bean>
2,参数校验
使用自带框架Hibernate Validator 是 JSR 303 的一个参考实现,除支持 所有标准的校验注解外,它还支持以下的扩展注解。
JSR 303自带
Hibernate Validator 增加的
使用步骤:
》引入jar包
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.9.Final</version>
</dependency>
》applicationContext.xml中在增加以下配置
<mvc:annotation-driven validator="validator" ></mvc:annotation-driven>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
</bean>
》javabean
public class User {
private Long id;
@NotEmpty
private String name;
private Integer age;
private Boolean gender;
@Email
private String email;
private Date birthday;
}
》控制器controller(不要忘了给参数加@Validated)
@RequestMapping("/toUser")//BindingResult:就是dataBinder做参数绑定时所有的错误信息
public String toUser(@Validated User user,BindingResult br, Model model ){
//得到所有的异常对象
List<ObjectError> allErrors = br.getAllErrors();
if(allErrors.size()!=0){
for(ObjectError o:allErrors){
System.out.println("发生错误啦");
//把错误放到model域里面可以在jsp里得到错误原因
model.addAttribute("error", o.getDefaultMessage());
return "error";
}
}
System.out.println("进来了。。。。。。");
System.out.println(user.toString());
return "aaa";
}
*3,如何拿到校验错误信息呢?====BindingResult*
通过在形参列表中加入BindingResult,可以判断有没有错误,同时加一个model域。可以在jsp拿到错误信息具体内容。(代码如上)
问题?1和2是怎么联合使用的?