AnnotationMethodHandlerAdapter和mvc:annotation-driven對型別轉換和HttpMessageConverter的配置
1. databind
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部分。
方式1:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="webBindingInitializer"> <bean class="com.management.utils.propeditor.BindingInitializer" /> </property> </bean> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" > </bean>
方式2:
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="net.zhepu.web.customerBinding.CustomerConverter" /> </list> </property> </bean> <mvc:annotation-driven validator="validator" conversion-service="conversionService" />
注意: 方式一通過 AnnotationMethodHandlerAdapter註冊webBindingInitializer來新增自定義型別轉換, 又通過ConversionServiceFactoryBean註冊預設的型別轉換。
方式二通過 mvc:annotation-driven來新增自定義轉換, mvc:annotation-driven 是spring 3後出現的新的標註, 他不能和AnnotationMethodHandlerAdapter同時使用, 否則會出現衝突。
2. HttpMessageConverter
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。
方式1:
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="com.management.utils.propeditor.BindingInitializer" />
</property>
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
方式2:
在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>同樣, 上面方式1和方式2的不能同時使用, 只能同時選用一種方式。