1. 程式人生 > >AnnotationMethodHandlerAdapter和mvc:annotation-driven對型別轉換和HttpMessageConverter的配置

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的不能同時使用, 只能同時選用一種方式。