springMVC源码4:HttpMessageConverter<T>和ConversionService之间怎么关联
来源:互联网 发布:行星齿轮设计软件 编辑:程序博客网 时间:2024/04/29 07:25
1 spring数据绑定:http://jinnianshilongnian.iteye.com/blog/1723270
2 springMVC中,HttpMessageConverter<T>和ConversionService之间的区别:http://www.iteye.com/problems/98525
ConversionService是属于spring core部分 所有spring管理的bean等等 都使用它进行类型转换,而它又需要注册一些converter 来完成类型转换。 这个可以看我博客 springmvc部分
HttpMessageConverter 是对http请求/响应 数据进行转换的, 它可以使用ConversionService进行一些转换(HttpMessageConverter是否能转换 还需要根据如请求的contentType等决定)
3 官方文档:
In a Spring MVC application, you may configure a custom ConversionService instance explicitly as an attribute of the annotation-driven element of
the MVC namespace. This ConversionService will then be used anytime a type conversion is required during Controller model binding. If not configured
explicitly, Spring MVC will automatically register default formatters and converters for common types such as numbers and dates.
翻译:
在Spring MVC应用程序中,您可以将自定义ConversionService实例显式配置为MVC命名空间的注释驱动元素的属性。 随后在Controller模型绑定期间需要进行类型转换时,将使用此ConversionService。 如果没有明确配置,Spring MVC将自动注册默认格式化程序和转换器,用于常见类型,如数字和日期。
<mvc:annotation-driven/>With this one-line of configuration, default formatters for Numbers and Date types will be installed, including support for the @NumberFormat and
@DateTimeFormat annotations. Full support for the Joda Time formatting library is also installed if Joda Time is present on the classpath.
To inject a ConversionService instance with custom formatters and converters registered, set the conversion-service attribute and then
specify custom converters, formatters, or FormatterRegistrars as properties of the FormattingConversionServiceFactoryBean:
通过这种一行配置,将使用默认“数字和日期”的格式化方法,包括对@NumberFormat和@DateTimeFormat注释的支持。 如果Joda时间存在于类路径上,
则还将完全支持Joda Time格式化库。要注册自定义格式化程序和转换器的ConversionService实例,请设置conversion-service属性,然后将使用自定义converters,
formatters或FormatterRegistrars,作为FormattingConversionServiceFactoryBean的三个属性:
代码:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="org.example.MyConverter"/> </set> </property> <property name="formatters"> <set> <bean class="org.example.MyFormatter"/> <bean class="org.example.MyAnnotationFormatterFactory"/> </set> </property> <property name="formatterRegistrars"> <set> <bean class="org.example.MyFormatterRegistrar"/> </set> </property> </bean></beans>
总结:
-----------------------------------------------分割线---下面的不用看了-------------------------------------------------
4 HttpMessageConverter<T>和ConversionService之间怎么关联: http://starscream.iteye.com/blog/1072179 正确性存疑
对于requestBody或httpEntity中数据的类型转换
Spring MVC中对于requestBody中发送的数据转换不是通过databind来实现,而是使用HttpMessageConverter来实现具体的类型转换。
例如,之前提到的json格式的输入,在将json格式的输入转换为具体的model的过程中,spring mvc首先找出request header中的contenttype,再遍历当前所注册的所有的HttpMessageConverter子类, 根据子类中的canRead()方法来决定调用哪个具体的子类来实现对requestBody中的数据的解析。如果当前所注册的httpMessageConverter中都无法解析对应contexttype类型,则抛出HttpMediaTypeNotSupportedException (http 415错误)。
那么需要如何注册自定义的messageConverter呢,很不幸,在spring 3.0.5中如果使用annotation-driven的配置方式的话,无法实现自定义的messageConverter的配置,必须老老实实的自己定义AnnotationMethodHandlerAdapter的bean定义,再设置其messageConverters以注册自定义的messageConverter。
在3.1版本中,将增加annotation-driven对自定义的messageConverter的支持 (SPR-7504),具体格式如下
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/> </mvc:message-converters> </mvc:annotation-driven>
Servlet中的输入参数为都是string类型,而spring mvc通过data bind机制将这些string 类型的输入参数转换为相应的command object(根据view和controller之间传输数据的具体逻辑,也可称为model attributes, domain model objects)。在这个转换过程中,spring实际是先利用java.beans.PropertyEditor中的 setAdText方法来把string格式的输入转换为bean属性,
亦可通过继承java.beans.PropertyEditorSupport来实现自定义的PropertyEditors,具体实现方式可参考spring reference 3.0.5 第 5.4节中的 Registering additional custom PropertyEditors部分。
自定义完毕propertyEditor后,有以下几种方式来注册自定义的customer propertyEditor.
1:直接将自定义的propertyEditor放到需要处理的java bean相同的目录下
名称和java Bean相同但后面带Editor后缀。
例如需要转换的java bean 名为User,则在相同的包中存在UserEditor类可实现customer propertyEditor的自动注册。
2:利用@InitBinder来注册customer propertyEditor
这个在之前的笔记中已经介绍过了,即在controller类中增加一个使用@InitBinder标注的方法,在其中注册customer Editor
- @InitBinder
- public void initBinder(WebDataBinder binder) {
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- dateFormat.setLenient(false);
- binder.registerCustomEditor(Date.class, new CustomDateEditor(
- dateFormat, false));
- }
3:继承 WebBindingInitializer 接口来实现全局注册
使用@InitBinder只能对特定的controller类生效,为注册一个全局的customer Editor,可以实现接口WebBindingInitializer 。
- public class CustomerBinding implements WebBindingInitializer {
- @Override
- public void initBinder(WebDataBinder binder, WebRequest request) {
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- dateFormat.setLenient(false);
- binder.registerCustomEditor(Date.class, new CustomDateEditor(
- dateFormat, false));
- }
并修改 servlet context xml配置文件
- <bean
- class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
- <property name="webBindingInitializer">
- <bean
- class="net.zhepu.web.customerBinding.CustomerBinding" />
- </property>
- </bean>
但这样一来就无法使用mvc:annotation-driven 了。
使用conversion-service来注册自定义的converter
DataBinder实现了PropertyEditorRegistry, TypeConverter这两个interface,而在spring mvc实际处理时,返回值都是return binder.convertIfNecessary(见HandlerMethodInvoker中的具体处理逻辑)。因此可以使用customer conversionService来实现自定义的类型转换。
- <bean id="conversionService"
- class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
- <property name="converters">
- <list>
- <bean class="net.zhepu.web.customerBinding.CustomerConverter" />
- </list>
- </property>
- lt;/bean>
需要修改spring service context xml配置文件中的annotation-driven,增加属性conversion-service指向新增的conversionService bean。
- <mvc:annotation-driven validator="validator" conversion-service="conversionService" />
实际自定义的converter如下。
- public class CustomerConverter implements Converter<String, Date> {
- @Override
- public Date convert(String source) {
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- dateFormat.setLenient(false);
- try {
- return dateFormat.parse(source);
- } catch (ParseException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
阅读文档发现Spring提供了基于<mvc:annotation-driven />自定义messageConverters的方法,
如下所示:(conversion-service="conversionService")
<mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。
这句话我在很多帖子都看到过,我自己的项目本身使用的Spring MVC 3.2,实际上在3.1之后,<mvc:annotation-driven />注册的类发生了变化
Spring Framework 3.1 introduces a new set of support classes for processing requests with annotated controllers:
RequestMappingHandlerMapping
RequestMappingHandlerAdapter
ExceptionHandlerExceptionResolver
These classes are a replacement for the existing:
DefaultAnnotationHandlerMapping
AnnotationMethodHandlerAdapter
AnnotationMethodHandlerExceptionResolver
The above registers a RequestMappingHandlerMapping
, a RequestMappingHandlerAdapter
, and an ExceptionHandlerExceptionResolver
(among others) in support of processing requests with annotated controller methods using annotations such as @RequestMapping
, @ExceptionHandler
, and others.
It also enables the following:
Spring 3 style type conversion through a ConversionService instance in addition to the JavaBeans PropertyEditors used for Data Binding.
Support for formatting Number fields using the
@NumberFormat
annotation through theConversionService
.Support for formatting Date, Calendar, Long, and Joda Time fields using the
@DateTimeFormat
annotation.Support for validating @Controller inputs with
@Valid
, if a JSR-303 Provider is present on the classpath.HttpMessageConverter support for
@RequestBody
method parameters and@ResponseBody
method return values from@RequestMapping
or@ExceptionHandler
methods.This is the complete list of HttpMessageConverters set up by mvc:annotation-driven:
ByteArrayHttpMessageConverter
converts byte arrays.StringHttpMessageConverter
converts strings.ResourceHttpMessageConverter
converts to/fromorg.springframework.core.io.Resource
for all media types.SourceHttpMessageConverter
converts to/from ajavax.xml.transform.Source
.FormHttpMessageConverter
converts form data to/from aMultiValueMap<String, String>
.Jaxb2RootElementHttpMessageConverter
converts Java objects to/from XML — added if JAXB2 is present on the classpath.MappingJackson2HttpMessageConverter
(orMappingJacksonHttpMessageConverter
) converts to/from JSON — added if Jackson 2 (or Jackson) is present on the classpath.AtomFeedHttpMessageConverter
converts Atom feeds — added if Rome is present on the classpath.RssChannelHttpMessageConverter
converts RSS feeds — added if Rome is present on the classpath.
RequestMappingHandlerMapping和
RequestMappingHandlerAdapter。
我之前在不知道的时候,使用AnnotationMethodHandlerAdapter 进行配置,结果在有<mvc:annotation-driven />存在的情况下,我自己配置的AnnotationMethodHandlerAdapter 怎么都不起作用,于是去掉了<mvc:annotation-driven />标签,手动注册了AnnotationMethodHandlerAdapter ,和DefaultAnnotationHandlerMapping。结果引发了其他问题,比如文件无法上传的问题。
阅读文档发现Spring提供了基于<mvc:annotation-driven />自定义messageConverters的方法,如下所示:
下面展示我自己的配置
- springMVC源码4:HttpMessageConverter<T>和ConversionService之间怎么关联
- springMVC源码5:HttpMessageConverter<T>和ConversionService之间怎么关联
- SpringMVC 中 HttpMessageConverter<T>
- springmvc之HttpMessageConverter<T>接口
- HttpMessageConverter<T>接口源码学习
- SpringMVC源码-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五) - 消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- SpringMVC源码剖析-消息转换器HttpMessageConverter
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
- 文章标题
- Could not determine the class-path for interface com.android.builder.model.NativeAndroidProjec
- Qt 二进制文件读写
- 前端实现微信分享
- 关于LINQ执行查询的解决
- springMVC源码4:HttpMessageConverter<T>和ConversionService之间怎么关联
- 屏幕尺寸获取
- Kotlin 官方学习教程之扩展
- 基于OpenLayer的室内地图前端设计开发
- 浅谈HTTP中Get与Post的区别
- BOS打开单据的时候出现:无法解决 equal to 运算中 "Chinese_PRC_CS_AS" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突。
- Kafka的入门简单命令
- laravel5.4整合极验验证码3.0
- Mybatis获取插入记录的自增长ID