1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java学习笔记——springmvc 之 数据自定义转换器 数据格式化 JSR303数据校验

java学习笔记——springmvc 之 数据自定义转换器 数据格式化 JSR303数据校验

时间:2019-12-07 11:32:16

相关推荐

java学习笔记——springmvc 之 数据自定义转换器  数据格式化  JSR303数据校验

九、数据绑定流程分析

1、提出问题

日期字符串格式的表单参数,提交后转换为Date类型

2、数据绑定流程原理★

Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建DataBinder实例对象DataBinder 调用装配在 Spring MVC 上下文中的ConversionService组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中调用Validator组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData对象Spring MVC 抽取BindingResult中的入参对象和校验错误对象,将它们赋给处理方法的响应入参

Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是DataBinder,运行机制如下:

3、通过debug调试流程

查看数据绑定流程,在Employee类的set方法上设置断点调试Spring MVC 上下文中内建了很多转换器,可完成大多数 Java 类型的转换工作。查看:StringToNumberConverterFactory源码,在getConverter()方法中设置断点,在执行set方法(性别字段)前会调用该方法。

4、自定义类型转换器

1、类型转换器概述

ConversionService是 Spring 类型转换体系的核心接口。可以利用ConversionServiceFactoryBean在 Spring 的 IOC 容器中定义一个

ConversionService.Spring将自动识别出IOC容器中的ConversionService,并在Bean属性配置及Spring MVC处理方法入参绑定等场合使用它进行数据的转换

可通过ConversionServiceFactoryBeanconverters属性注册自定义的类型转换器例如:

2、Spring 支持的转换器类型

Spring 定义了 3 种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到 ConversionServiceFactoryBean 中:

Converter<S,T>:将 S 类型对象转为 T 类型对象ConverterFactory:将相同系列多个 “同质” Converter 封装在一起。如果希望将一种类型的对象转换为另一种类型及其子类的对象(例如将 String 转换为 Number 及 Number 子类(Integer、Long、Double 等)对象)可使用该转换器工厂类GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型转换

3、自定义转换器示例

需求:字符串转换为对象。

步骤:

定义页面控制器方法自定义类型转换器声明类型转换器服务<mvc:annotation-driven conversion-service="conversionService"/> 会将自定义的

ConversionService 注册到 Spring MVC 的上下文中

5、debug调试

增加新的转换器,之前的转换器是否还好使呢?好使。

查看,框架出厂设置,与目前将我们的自定义类型转换器加入出厂设置中。

当配置了<mvc:annotation-driven/>后,会自动加载

org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

和org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

6、<mvc:annotation-driven/>配置在什么时候必须配置?

直接配置响应的页面:无需经过控制器来执行结果 ;但会导致其他请求路径失效,需要配置mvc:annotation-driven标签RESTful-CRUD操作,删除时,通过jQuery执行delete请求时,找不到静态资源,需要配置mvc:annotation-driven标签配置类型转换器服务时,需要指定转换器服务引用

<mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的

ConversionService 注册到 Spring MVC 的上下文中

后面完成JSR 303数据验证,也需要配置

7、关于 <mvc:annotation-driven /> 作用

<mvc:annotation-driven /> 会自动注册:

RequestMappingHandlerMappingRequestMappingHandlerAdapter

ExceptionHandlerExceptionResolver三个bean。

还将提供以下支持:支持使用ConversionService实例对表单参数进行类型转换支持使用@NumberFormat@DateTimeFormat注解完成数据类型的格式化支持使用@Valid注解对 JavaBean 实例进行 JSR 303 验证支持使用@RequestBody@ResponseBody注解结合源码分析(在bean对象的set方法上设置断点进行调试)既没有配置<mvc:default-servlet-handler/>也没有配置<mvc:annotation-driven/>

都没有配置情况下,AnnotationMethodHandlerAdapter是默认出厂设置,干活的(过期)

另外:conversionService是null(类型转换器是不起作用的)

配置了<mvc:default-servlet-handler/>但没有配置<mvc:annotation-driven/>

AnnotationMethodHandlerAdapter被取消,解决了静态资源查找,但是@RequestMapping不好使了。

既配置了<mvc:default-servlet-handler/>又配置<mvc:annotation-driven/>【重要】

AnnotationMethodHandlerAdapter被替换成RequestMappingHandlerAdapter来干活了。

如果没有配置<mvc:annotation-driven/>标签时,conversionServicenull.

AnnotationMethodHandlerAdapter已经过时,Spring3.2推荐RequestMappingHandlerAdapter来替代。所以说,默认情况下,没有配置这两个配置时,HelloWorld 程序可以正常运行,但是,涉及到静态资源查找的时候,就必须配置这个<mvc:annotation-driven/>配置了

8、InitBinder注解

@InitBinder由@InitBinder标识的方法,可以对WebDataBinder对象进行初始化。WebDataBinder 是 DataBinder 的子类,用于完成由表单字段到 JavaBean 属性的绑定@InitBinder方法不能有返回值,它必须声明为void。@InitBinder方法的参数通常是WebDataBinder实验代码

9、数据的格式化

1、数据格式化概述

对属性对象的输入/输出进行格式化,从其本质上讲依然属于 “类型转换” 的范畴。Spring 在格式化模块中定义了一个实现 ConversionService 接口的

FormattingConversionService实现类,该实现类扩展了 GenericConversionService,因此它既具有类型转换的功能,又具有格式化的功能

FormattingConversionService 拥有一个FormattingConversionServiceFactroyBean工厂类,后者用于在 Spring 上下文中构造前者,FormattingConversionServiceFactroyBean 内部已经注册了 : NumberFormatAnnotationFormatterFactroy:支持对数字类型的属性使用

@NumberFormat注解

JodaDateTimeFormatAnnotationFormatterFactroy:支持对日期类型的属性使用

@DateTimeFormat 注解

装配了 FormattingConversionServiceFactroyBean 后,就可以在 Spring MVC 入参绑定及模型数据输出时使用注解驱动了。<mvc:annotation-driven/>默认创建的ConversionService实例即为

DefaultFormattingConversionService

2、日期格式化概述

@DateTimeFormat注解可对java.util.Datejava.util.Calendarjava.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、数值格式化概述

@NumberFormat可对类似数字类型的属性进行标注,它拥有两个互斥的属性: style:类型为 NumberFormat.Style。用于指定样式类型,包括三种:Style.NUMBER(正常数字类型)、Style.CURRENCY(货币类型)、Style.PERCENT(百分数类型)pattern:类型为 String,自定义样式,如pattern="#,###";

4、实验代码(格式化日期)

页面表单Employee类增加日期对象属性关于格式错误(框架默认支持的格式为斜线方式。1990/09/09)

在页面上设置格式为:1990-09-09

报错:

解决400错误:

在Employee类的日期属性上增加

配置,配置时不能指定conversion-service属性,否则,依然报错400。

FormattingConversionServiceFactoryBean替换ConversionServiceFactoryBean后再进行引用。

5、实验代码(格式化数字)

10、JSR303数据校验

下载地址:/download/qq_25106373/10626741

1、如何校验

①使用JSR 303验证标准

②加入hibernate validator验证框架

③在SpringMVC配置文件中增加<mvc:annotation-driven/>

④需要在bean的属性上增加对应验证的注解

⑤在目标方法bean类型的前面增加@Valid注解

2、验证出错后,跳转到哪个页面

3、错误消息,如何显示,如何国际化

4、JSR 303

是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中 .

JSR 303 (Java Specification Requests意思是Java 规范提案)通过Bean属性上标注类似于 @NotNull、@Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean 进行验证

5、Hibernate Validator 扩展注解

Hibernate Validator是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解

6、Spring MVC 数据校验

Spring 4.0 拥有自己独立的数据校验框架,同时支持 JSR 303 标准的校验框架。Spring 在进行数据绑定时,可同时调用校验框架完成数据校验工作。Spring MVC中,可直接通过注解驱动的方式进行数据校验Spring 的 LocalValidatorFactroyBean 既实现了 Spring 的 Validator 接口,也实现了 JSR 303 的 Validator 接口。只要在 Spring 容器中定义了一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的 Bean 中。Spring本身并没有提供 JSR303的实现,所以必须将 JSR303的实现者的 jar包放到类路径下<mvc:annotation-driven/>会默认装配好一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解即可让 Spring MVC 在完成数据绑定后执行数据校验的工作在已经标注了 JSR303 注解的表单/命令对象前标注一个 @Valid,Spring MVC 框架在将请求参数绑定到该入参对象后,就会调用校验框架根据注解声明的校验规则实施校验

7、实验代码

添加jar包:

hibernate-validator-5.0.0.CR2\dist

hibernate-validator-5.0.0.CR2.jarhibernate-validator-annotation-processor-5.0.0.CR2.jar

hibernate-validator-5.0.0.CR2\dist\lib\required (EL就不需要加了)

classmate-0.8.0.jarjboss-logging-3.1.1.GA.jarvalidation-api-1.1.0.CR1.jar在验证属性上增加验证注解增加后台打印错误消息前台打印错误消息测试验证,解决EL表达式错误

拷贝hibernate-validator-5.0.0.CR2\dist\lib\required目录下的

el-api-2.2.jar、javax.el-2.2.4.jar、javax.el-api-2.2.4.jar

三个包到Tomcat/lib目录下,将原来的el-api.jar删除。重启tomcat6

如果希望验证失败,回到添加页面public interface BindingResult extends ErrorsSpring MVC 是通过对处理方法签名的规约来保存校验结果的:前一个表单/命令对象的校验结果保存到随后的入参中,这个保存校验结果的入参必须是 BindingResult或 Errors类型,这两个类都位于 org.springframework.validation 包中需校验的 Bean对象和其绑定结果对象或错误对象是成对出现的,它们之间不允许声明其他的入参Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或 getFieldErrors(String field)BindingResult 扩展了 Errors 接口

8、如果类型转换失败,如何获取错误消息

(后台获取错误消息,并打印)

11、错误消息的显示及国际化

1、在页面上显示错误

Spring MVC 除了会将表单/命令对象的校验结果保存到对应的 BindingResult 或 Errors 对象中外,还会将所有校验结果保存到“隐含模型”即使处理方法的签名中没有对应于表单/命令对象的结果入参,校验结果也会保存在 “隐含对象” 中。隐含模型中的所有数据最终将通过 HttpServletRequest 的属性列表暴露给 JSP 视图对象,因此在 JSP 中可以获取错误信息在 JSP 页面上可通过<form:errors path=userName>显示错误消息

2、示例:

在表单上页面上显示所有的错误消息显示某一个表单域的错误消息有错,回到add.jsp

12、提示消息的国际化

每个属性在数据绑定和数据校验发生错误时,都会生成一个对应的 FieldError 对象。当一个属性校验失败后,校验框架会为该属性生成4个消息代码,这些代码以校验注解类名为前缀,结合modleAttribute、属性名及属性类型名生成多个对应的消息代码:例如 User 类中的 password 属性标注了一个 @Pattern 注解,当该属性值不满足 @Pattern 所定义的规则时, 就会产生以下 4 个错误代码:Pattern.user.passwordPattern.passwordPattern.java.lang.StringPattern当使用 Spring MVC 标签显示错误消息时, Spring MVC 会查看 WEB 上下文是否装配了对应的国际化消息,如果没有,则显示默认的错误消息,否则使用国际化消息。若数据类型转换或数据格式转换时发生错误,或该有的参数不存在,或调用处理方法时发生错误,都会在隐含模型中创建错误消息。其错误代码前缀说明如下:required:必要的参数不存在。如 @RequiredParam(“param1”) 标注了一个入参,但是该参数不存在typeMismatch:在数据绑定时,发生数据类型不匹配的问题methodInvocation:Spring MVC 在调用处理方法时发生了错误注册国际化资源文件

13、提示消息的国际化实验

定义国际化资源文件:i18n.properties声明国际化资源配置

14、返回JSON

1、处理 JSON

加入 jar 包:

/JacksonDownload/ 下载地址:/download/qq_25106373/10626744

jackson-annotations-2.1.5.jar

jackson-core-2.1.5.jar

jackson-databind-2.1.5.jar

编写目标方法,使其返回 JSON 对应的对象或集合增加页面代码:index.jsp测试

15、HttpMessageConverter原理

1、HttpMessageConverter<T>

HttpMessageConverter<T>是 Spring3.0 新添加的一个接口,负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息HttpMessageConverter<T>接口定义的方法:Boolean canRead(Class<?> clazz,MediaType mediaType): 指定转换器可以读取的对象类型,即转换器是否可将请求信息转换为 clazz 类型的对象,同时指定支持 MIME 类型(text/html,applaiction/json等)Boolean canWrite(Class<?> clazz,MediaType mediaType):指定转换器是否可将 clazz 类型的对象写到响应流中,响应流支持的媒体类型在MediaType 中定义。List<MediaType> getSupportMediaTypes():该转换器支持的媒体类型。T read(Class<? extends T> clazz,HttpInputMessageinputMessage):将请求信息流转换为 T 类型的对象。void write(T t,MediaType contnetType,HttpOutputMessgaeoutputMessage):将T类型的对象写到响应流中,同时指定相应的媒体类型为 contentType。DispatcherServlet 默认装配 RequestMappingHandlerAdapter ,

而 RequestMappingHandlerAdapter 默认装配如下 HttpMessageConverter:

加入 jackson jar 包后, RequestMappingHandlerAdapter

装配的 HttpMessageConverter 如下:

默认情况下数组长度是6个;增加了jackson的包,后多个一个

MappingJackson2HttpMessageConverter

16、使用HttpMessageConverter

使用HttpMessageConverter<T>将请求信息转化并绑定到处理方法的入参中或将响应结果转为对应类型的响应信息,Spring提供了两种途径: 使用@RequestBody / @ResponseBody对处理方法进行标注使用HttpEntity<T> / ResponseEntity<T>作为处理方法的入参或返回值当控制器处理方法使用到 @RequestBody/@ResponseBody 或

HttpEntity<T>/ResponseEntity<T> 时, Spring首先根据请求头或响应头的Accept属性选择匹配的HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错

@RequestBody@ResponseBody不需要成对出现Content-Disposition:attachment; filename=abc.pdf实验代码实验代码源码参考HttpHeadersHttpStatus G M T文本转语音功能仅限200个字符

java学习笔记——springmvc 之 数据自定义转换器 数据格式化 JSR303数据校验返回与接收JSON(@RequestBody 和 @ResponseBody)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。