转:SpringMVC 4.1 新特性(二)内容协商视图
阅读原文时间:2023年07月09日阅读:1

SpingMVC的内容协商支持三种方式:

  • 使用后缀,如jsonxml后缀和处理类型的关系可以自己定义
  • 前面说的使用Accept
  • 在访问时request请求的参数,比如每次请求request都会加format=xml参数,表示要求返回XML格式数据,默认参数名是format,可以修改。

SpingMVC规定,如果同时开启了上面的部分或全部方式,解析顺序是后缀参数Accept头。对我来说,还是比较喜欢用Accept头,用的时间长,比较适应。

SpingMVC文件中的配置方式如下:

<!-- Make this available across all of Spring MVC -->
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

<!-- Total customization - see below for explanation. -->
<bean id="contentNegotiationManager"
             class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="true" />
    <property name="favorParameter" value="false" />
    <property name="parameterName" value="format" />
    <property name="ignoreAcceptHeader" value="false"/>
    <property name="useJaf" value="false"/>
    <property name="defaultContentType" value="text/html" />

    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
       </map>
    </property>
</bean>
  • favorPathExtension参数表示是否开启后缀,默认true。(使用形如/account/a.json/account/a.xml的方式)
  • favorParameter参数表示是否开启request参数识别,默认false。(使用形如/account/a?format=json/account/?format=xml的方式)
  • parameterName参数表示使用参数的名字,默认format,如果配置为mediaType,则请求格式变为/account/a?mediaType=json
  • ignoreAcceptHeader表示是否关闭accept头识别,默认false,即默认开启accept头识别。
  • defaultContentType表示服务器默认的MediaType类型。
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="0"/>
    <property name="contentNegotiationManager" ref="contentNegotiationManager"/><!-- 如已配置过管理器,这里可以不配置 -->
    <property name="viewResolvers"><!-- 这里也可以配置viewResolver -->
        <list>
            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/views/" />
                <property name="suffix" value=".jsp" />
            </bean>
        </list>
    </property>
    <property name="defaultViews">
        <list>
            <!-- 不加配置返回 {"account":{"username":"admin","password":"123456"}} -->
            <!-- 加配置返回 {"username":"admin","password":"123456"}-->
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                <property name="extractValueFromSingleKeyModel" value="true" />
            </bean>
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <property name="marshaller">
                      <bean class="org.springframework.oxm.xstream.XStreamMarshaller"/>
                </property>
            </bean>
        </list>
    </property>
</bean>

Spring4.1之后提供了视图解析器标签,可以用如下方式

<mvc:view-resolvers>
    <mvc:content-negotiation>
        <mvc:default-views>
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                <property name="jsonpParameterNames">
                    <set>
                        <value>jsonp</value>
                        <value>callback</value>
                    </set>
                </property>
                <!-- 不加配置返回 {"account":{"username":"admin","password":"123456"}}
                     加配置返回 {"username":"admin","password":"123456"} -->
                <property name="extractValueFromSingleKeyModel" value="true" />
            </bean>
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <property name="marshaller">
                    <bean class="org.springframework.oxm.xstream.XStreamMarshaller">
                        <!-- 启用annotation -->
                            <property name="autodetectAnnotations" value="true" />
                    </bean>
                </property>
            </bean>
        </mvc:default-views>
    </mvc:content-negotiation>
    <mvc:jsp prefix="/WEB-INF/views/" suffix=".jsp" />
</mvc:view-resolvers>

mvc:content-negotiation用于定义内容协商的视图解析器,且内部可以定义默认视图;然后我们又定义了mvc:velocitymvc:groovy两个视图解析器;它们会按照顺序进行解析。另外几个视图解析器是:

  • mvc:freemarker

  • mvc:bean-name

  • mvc:jsp

    @Controller
    public class AccountController {

    /**
     * <p>.json结尾返回json</p>
     * <p>.xml结尾返回xml</p>
     */
    @GetMapping(value="viewResolver")
    public ModelAndView viewResolver(){
        ModelAndView mv = new ModelAndView();
        Account account = new Account(WebUtil.getRequest().getParameter("username"),
                WebUtil.getRequest().getParameter("password"));
        mv.addObject(account);
        mv.setViewName("viewResolver");
        return mv;
    }
    @GetMapping(value="viewResolver2")
    public String viewResolver2(Model model){
        Account account = new Account(WebUtil.getRequest().getParameter("username"),
                WebUtil.getRequest().getParameter("password"));
        model.addAttribute(account);
        return "viewResolver";
    }
    
    @XStreamAlias("account")
    public static class Account{
    private String username;
    
    private String password;
    
    public Account(){}
    
    public Account(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }
    //getter setter
    
    @Override
    public String toString() {
        return "account:{"+username+"|"+password+"}";
    }
    }

    }