Spring MVC 3.x 消息轉換器

RESTFul或Ajax都是根據一個合約(固定的文件擴展名或Http請求頭的Accept)來獲得某種格式的數據響應.

圖1

不用消息轉換器也可以實現.來看一看以下示例

    @RequestMapping(value="/favorite",method=RequestMethod.POST,produces = "application/json; charset=utf-8")
    @ResponseBody
    public String favoriteArticle(@RequestParam String hash){
        if(!aO.isOnline()) return "{}";

        TipMessage msg=null;
        if( articleService.addFavorite(hash, aO.getUid())){
            msg=new TipMessage("收藏成功",TipMessageLevel.ACC);
        }else{
            msg=new TipMessage("已經完成收藏");
        }
        //使用某個Json框架把對象轉換成String
        return msg.showJson();
    }

對於xml內容的響應不用消息轉換器也可以實現.最簡單的是用JAXB,把一個把對象轉換成String.

如果這種需求在項目中大量出現,你可以把他們歸到一個WEB服務項目,使用Jersey框架或其它的WEB服務框架來實現,如果還至於把他們歸到一個項目.哪看看Spring MVC的消息轉換器吧.

spring mvc配置文件

    <!-- 開啓Spring mvc 註解支持 -->
    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
       <mvc:message-converters register-defaults="true">
            <!-- 將StringHttpMessageConverter的默認編碼設爲UTF-8 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8" />
            </bean>
            <!-- 將Jackson2HttpMessageConverter的默認格式化輸出爲false -->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
                <property name="prettyPrint" value="false" />
                <property name="objectMapper">
                    <bean class="net.labdemo.common.mapper.JsonMapper"></bean>
                </property>
            </bean>
             <!-- 使用 Spring 的 marshaller/un-marshaller 讀取/編寫 XML 數據,轉換媒體類型爲 application/xml 的數據 -->
            <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
                <constructor-arg ref="jaxb2Marshaller" />
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/xml;charset=UTF-8</value>
                        <value>application/xml;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
       </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- JAXB to XML -->
    <bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <!-- 按命名包掃描 -->
        <property name="packagesToScan" value="net.labdemo.entity"></property>
        <!-- 按命名類掃描 -->
    </bean>
    <!-- 根據URL後綴自動判定Content-Type及相應的View -->
    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="mediaTypes">
            <map>
                <entry key="xml" value="application/xml" />
                <entry key="json" value="application/json" />
            </map>
        </property>
        <property name="ignoreAcceptHeader" value="true" />
        <property name="favorPathExtension" value="true" />
    </bean>

只貼出了與消息轉換器有關的配置.配置中用到的jar,下面是maven

        <!-- http://mvnrepository.com/artifact/org.springframework/spring-oxm -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <!-- http://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
        <!-- 不啓用xstream可以刪除 -->
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.7</version>
        </dependency>
        <!-- http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <!-- http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <!-- http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jaxb-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>

net.labdemo.common.mapper.JsonMapper在此文的附件中可以下載到,用了fasterxml.Spring MVC控制器中的方法只需要加上:@ResponseBody註解,方法的返回值直接寫類型(實體,List<實體>或其它集合)即可

上面的配置是用擴展名來識別消息轉換器.測試如下圖

圖2

如果希望用Http請求頭的Accept來識別消息轉換器.contentNegotiationManager Bean作以下變更(圖1就是以下配置的截圖)

    <!-- REST中根據URL後綴自動判定Content-Type及相應的View -->
    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="ignoreAcceptHeader" value="false" />
        <property name="favorPathExtension" value="true" />
    </bean>

最後
1.
net.labdemo.entity包下的實體是需要加Jaxb註解的.關於註解的說明參考

jaxb中的類繼承

2.
Spring MVC+Spring的基礎配置文件參考
Spring Mvc+Spring+Mybatis(SSM)基礎配置文件

3.
使用Jersey架設RESTFul服務
jersey服務端簡單小示例

4.
JsonMapper源碼

5.
對於xml消息轉換器還可以使用:XStreamMarshaller
示例:

            <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
                <constructor-arg>
                    <bean class="org.springframework.oxm.xstream.XStreamMarshaller">
                        <property name="streamDriver">
                            <bean class="com.thoughtworks.xstream.io.xml.StaxDriver" />
                        </property>
                        <property name="annotatedClasses">
                            <list>
                                <value>net.labdemo.common.entity.BaseEntity</value>
                            </list>
                        </property>
                    </bean>
                </constructor-arg>
                <property name="supportedMediaTypes" value="application/xml"></property>
            </bean>

該方案需要多一些依賴

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章