文章目录
SpringMVC之数据处理
一 数据转换
1 数据绑定流程
- Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,来创建 DataBinder 实例对象
- DataBinder 调用装配在 Spring MVC 上下文中的ConversionService 组件进行数据类型转换、数据格式 化工作。将 Servlet 中的请求信息填充到入参对象中
- 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData 对象
- Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参
- Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是 DataBinder,运行机制如下:
- debug查看以上对象
2 数据转换器
-
Spring MVC 上下文中内建了很多转换器,可完成大多数 Java 类型的转换工作。
-
自定义类型转换器
(1)ConversionService 是 Spring 类型转换体系的核心接口。
(2)可以利用 ConversionServiceFactoryBean 在 Spring 的 IOC 容器中定义一个 ConversionService. Spring 将自动识别出 IOC 容器中的 ConversionService,并在 Bean 属性配置及 Spring MVC 处理方法入参绑定等场合使用它进行数据的转换
(3)可通过 ConversionServiceFactoryBean 的 converters 属性注册自定义的类型转换器
-
spring支持的转换器
spring定义了3种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到 ConversionServiceFactroyBean 中
(1)Converter<S,T>:将 S 类型对象转为 T 类型对象
(2)ConverterFactory:将相同系列多个 “同质” Converter 封装在一 起。如果希望将一种类型的对象转换为另一种类型及其子类的对象(例如将 String 转换为 Number 及 Number 子类 (Integer、Long、Double 等)对象)可使用该转换器工厂类
(3)GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型转换
(4) 自定义转换器案例
① 自定义转换器实现转换器接口,重写convert方法
② 注册到springmvc中
<mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的 ConversionService 注册到 Spring MVC 的上下文中
-
mvc:annotation-driven
mvc:annotation-driven 会自动注册RequestMappingHandlerMapping 、RequestMappingHandlerAdapter 与 ExceptionHandlerExceptionResolver 三个bean。
还将提供以下支持:
① 支持使用 ConversionService 实例对表单参数进行类型转换
② 支持使用 @NumberFormat annotation、@DateTimeFormat 注解完成数据类型的格式化
③ 支持使用 @Valid 注解对 JavaBean 实例进行 JSR 303 验证
④ 支持使用 @RequestBody 和 @ResponseBody 注解 -
@InitBinder
(1)由 @InitBinder 标识的方法,可以对 WebDataBinder对象进行初始化。WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定
(2)@InitBinder方法不能有返回值,它必须声明为void
(3)@InitBinder方法的参数通常是 WebDataBinder
二 数据格式化
1. 数据格式化
(1)对属性对象的输入/输出进行格式化,从其本质上讲依然属于 “类型转换” 的范畴
(2)Spring 在格式化模块中定义了一个实现 ConversionService 接口的 **FormattingConversionService** 实现类,该实现类扩展 了 GenericConversionService,因此它既具有类型转换的 功能,又具有格式化的功能
(3)FormattingConversionService 拥有一个 **FormattingConversionServiceFactroyBean** 工厂类, 后者用于在 Spring 上下文中构造前者
(4)FormattingConversionServiceFactroyBean 内部已经注册了 :
① **NumberFormatAnnotationFormatterFactroy**:支持对数字类型的属性使用 **@NumberFormat** 注解
② **JodaDateTimeFormatAnnotationFormatterFactroy**:支持对日期类型– 的属性使用 **@DateTimeFormat** 注解
(5)装配了 FormattingConversionServiceFactroyBean 后,就可以在 Spring MVC 入参绑定及模型数据输出时使用注解驱动 了。<mvc:annotation-driven/> 默认创建的 ConversionService 实例即为 FormattingConversionServiceFactroyBean
2. 日期格式化
(1)**@DateTimeFormat** 注解可对 java.util.Date、java.util.Calendar、java.long.Long 时间类型进行标注:
① **pattern** 属性:类型为字符串。指定解析/格式化字段数据的模式,如:”yyyy-MM-dd hh:mm:ss”
② iso 属性:类型为 DateTimeFormat.ISO。指定解析/格式化字段数据的ISO模式,包括四种:ISO.NONE(不使用) -- 默 认、ISO.DATE(yyyy-MM-dd) 、ISO.TIME(hh:mm:ss.SSSZ)、 ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ)
③ style 属性:字符串类型。通过样式指定日期时间的格式,由两位字– 符组成,第一位表示日期的格式,第二位表示时间的格式:S:短日 期/时间格式、M:中日期/时间格式、L:长日期/时间格式、F:完整 日期/时间格式、-:忽略日期或时间格式
3. 数值格式化
(1)**@NumberFormat** 可对类似数字类型的属性进行标注,它拥有两个互斥的属性:
① style:类型为 NumberFormat.Style。用于指定样式类– 型,包括三种:**Style.NUMBER**(正常数字类型)、 **Style.CURRENCY**(货币类型)、 **Style.PERCENT**( 百分数类型)
② pattern:类型为 String,自定义样式, 如patter="#,###";
4. 格式化案例
三 数据校验
1. JSR303介绍
(1)JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中
(2)JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210329162130354.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hjeXhzaA==,size_16,color_FFFFFF,t_70)
2. Hibernate Validator 扩展注解
Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210329162311100.png)
3. SpringMVC数据校验
(1)Spring 4.0 拥有自己独立的数据校验框架,同时支持 JSR 303 标准的校验框架
(2)Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。在 Spring MVC 中,**可直接通过注解驱动的方式 进行数据校验**
(3)Spring 的 **LocalValidatorFactroyBean** 既实现了 Spring 的 Validator 接口,也实现了 JSR 303 的 Validator 接口。只要 在 Spring 容器中定义了一个 LocalValidatorFactoryBean,即可将其注入到需要数据校 验的 Bean 中
(4)Spring 本身并没有提供 JSR303 的实现,所以必须将 **JSR303 的实现者的 jar 包放到类路径下**
(5)<mvc:annotation-driven/> 会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的**入参上标 注@valid** 注解即可让 Spring MVC 在完成数据绑定后执行 数据校验的工作
(6)在已经标注了 JSR303 注解的**表单/命令对象**前标注一个 **@Valid**,Spring MVC 框架在将请求参数绑定到该入参对象 后,就会调用校验框架根据注解声明的校验规则实施校验
(7)Spring MVC 是**通过对处理方法签名的规约来保存校验结果的**:前一个表单/命令对象的校验结果保存到随后的入参 中,这个保存校验结果的入参必须是 BindingResult 或 Errors 类型,这两个类都位于org.springframework.validation 包
(8)**需校验的 Bean 对象和其绑定结果对象或错误对象是成对出现的,它们之间不允许声明其他的入参**
(9)Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或 getFieldErrors(String field) ,BindingResult 扩展了 Errors 接口![在这里插入图片描述](https://img-blog.csdnimg.cn/20210329163422956.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hjeXhzaA==,size_16,color_FFFFFF,t_70)
4. 在目标方法中获取校验结果
(1)在表单/命令对象类的属性中标注校验注解,在处理方法对应的入参前添加 @Valid,Spring MVC 就会实施校验并将校 验结果保存在被校验入参对象之后的 BindingResult 或 Errors 入参中
(2)常用方法:
① FieldError getFieldError(String field)
② List<FieldError> getFieldErrors()
③ Object getFieldValue(String field)
④ Int getErrorCount()
5. 在页面上显示错误
(1)Spring MVC 除了会将表单/命令对象的校验结果保存到对应的 BindingResult 或 Errors 对象中外,还会将所有校验 结果保存到 “隐含模型“
(2)即使处理方法的签名中没有对应于表单/命令对象的结果入参,校验结果也会保存在 “隐含对象” 中
(3)隐含模型中的所有数据最终将通过 **HttpServletRequest** 的属性列表暴露给 JSP 视图对象,因此在 JSP 中可以获取 错误信息
(4)在 JSP 页面上可通过 <form:errors path=“userName”> 显示错误消息
6. 提示信息的国际化
(1)若数据类型转换或数据格式转换时发生错误,或该有的参数不存在,或调用处理方法时发生错误,都会在隐含模型 中创建错误消息。其错误代码前缀说明如下:
① **required**:必要的参数不存在。如@RequiredParam(“param1”) 标注了一个入参,但是该参数不存在
② **typeMismatch**:在数据绑定时,发生数据类型不匹配的问题
③ **methodInvocation**:Spring MVC 在调用处理方法时发生了错误
(2)注册国际化资源文件![在这里插入图片描述](https://img-blog.csdnimg.cn/20210329165027837.png)
四 案例
(1)index.jsp
(2)实体类
(3)目标方法