如何在Controller - Spring MVC中更改视图的mediaType

时间:2014-10-27 07:12:36

标签: spring spring-mvc content-negotiation

我使用http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc实现了内容协商。

我有一个控制器ProviderController&该控制器中的所有视图都附加了web.xml中的.action

<servlet-mapping>
    <servlet-name>provider</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

如果需要在html中呈现任何视图,我使用格式查询参数(例如:renderHtml.action?format = html)。如何在不使用格式查询参数的情况下以其他格式呈现页面?

P.S:我使用的是Spring 3.0。我不能使用生成注释。

由于

编辑:

provider-servlet.xml中的viewresolver配置

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="favorParameter" value="true" />
    <property name="parameterName" value="format" />
    <property name="ignoreAcceptHeader" value="true" />
    <property name="defaultContentType" value="application/json" />
    <property name="favorPathExtension" value="false" />
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="html" value="text/html" />
        </map>
    </property>

    <property name="viewResolvers">
        <list>
            <bean
                class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/provider/" />
                <property name="suffix" value=".jsp" />
            </bean>
        </list>
    </property>

    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
        </list>
    </property>
</bean>

web.xml:

<servlet>
    <servlet-name>provider</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>\WEB-INF\provider-servlet.xml</param-value>
    </init-param>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
    </init-param>       
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>provider</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

控制器:

//The below one returns token.jsp if directly opened in browswer as http://localhost/provider/setToken.action?format=html
@RequestMapping("/provider/setToken")
public String setToken(WebRequest webRequest, Model model, HttpServletRequest request) {
    return "token";
}

//The below one returns json if directly opened in browswer as http://localhost/provider/main.action if format=html is not provided.
@RequestMapping("/provider/main")
public String main(WebRequest webRequest, Model model, HttpServletRequest request) {
    return "main";
}

1 个答案:

答案 0 :(得分:0)

它在链接中表示正确,PPA(路径,参数,接受)策略

  • 路径 - 您正在使用.action,因此它不适用
  • 参数 - 您想要远离此
  • 接受标题 - 所以您剩下的就是在请求中使用Accept标头

确保在ContentNegtiationViewResolverBean中将ignoreAcceptHeader设置为true

想想最简单的控制器方法

@RequestMapping(value = "/post", method = RequestMethod.POST)
public String post() {
    return "main";
}

如果您发送两个带有不同接受标头的ajax请求,例如。 jquery的

    $.ajax({
        headers: {
            Accept: "application/json"
        },
        url: 'http://localhost:8091/post',
        type: 'POST',
        contentType: 'application/json',
        success: function () {
            console.log('success json');
        },
        error: function () {
            console.log('error');
        }
    });

    $.ajax({
        headers: {
            Accept: "text/html;charset=UTF-8"
        },
        url: 'http://localhost:8091/post',
        type: 'POST',
        contentType: 'text/html',
        success: function () {
            console.log('success');
        },
        error: function () {
            console.log('error');
        }
    })

假设你有一个main.jsp,并且你在conf中添加了JsonView解析器

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
   <property name="order" value="1"/>
   <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json"/>
        </map>
    </property>
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
        </list>
    </property>
</bean>

这两个方法的响应首先是JSON,第二个是text / html