4

我对 Spring MVC 和 REST 有疑问。问题是,当我发布一个没有扩展名的 url 或除 json 或 html 或 htm 之外的任何扩展名时,我总是得到一个 xml 响应。但我希望它默认为 text/html 响应。我正在搜索许多主题,但找不到对此的答案。

这是我的控制器类:

@RequestMapping(value="/user/{username}", method=RequestMethod.GET)
public String showUserDetails(@PathVariable String username, Model model){
    model.addAttribute(userManager.getUser(username));
    return "userDetails";
}

@RequestMapping(value = "/user/{username}", method = RequestMethod.GET,   
        produces={"application/xml", "application/json"})  
@ResponseStatus(HttpStatus.OK)
public @ResponseBody 
    User getUser(@PathVariable String username) {
    return userManager.getUser(username);
}

这是我的 mvc 上下文配置:

<mvc:resources mapping="/resources/**"
    location="/resources/"/>

<context:component-scan
    base-package="com.chodak.controller" />


    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <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>

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass">
        <value>
            org.springframework.web.servlet.view.tiles3.TilesView
        </value>
    </property>
</bean>
<bean id="tilesConfigurer"
    class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/tiles.xml</value>
        </list>
    </property>
</bean>

实际上,当我尝试内置的 Eclipse 浏览器时,它工作正常,但是当我使用 firefox 或 chrome 时,它​​会在没有扩展名的请求上显示 xml 响应。我尝试使用ignoreAcceptHeader,但没有改变。

也适用于 IE:/

如果有人有想法请帮忙,谢谢。

4

2 回答 2

1

我实际上发现了如何做到这一点,我真的不明白为什么但它现在正在工作,我向 contentresolver 添加了默认视图,例如:

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

      <!-- JAXB XML View -->
      <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
        <constructor-arg>
            <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
               <property name="classesToBeBound">
                <list>
                   <value>com.chodak.tx.model.User</value>
                </list>
               </property>
            </bean>
        </constructor-arg>
      </bean>
     </list>
  </property>

并删除了 getUser 方法,该方法被注释为生成 xml 和 json。如果我将其保留为添加的默认视图,它仍然无法正常工作。如果有人能解释为什么它会很棒:)

于 2013-12-05T10:47:22.863 回答
0

你可以做

import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
// @EnableWebMvc already autoconfigured by Spring Boot
public class MvcConfiguration {

@Bean
public WebMvcConfigurer contentNegotiationConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.favorPathExtension(false)
                    .favorParameter(true)
                    .parameterName("mediaType")
                    .ignoreAcceptHeader(true)
                    .useJaf(false)
                    .defaultContentType(MediaType.APPLICATION_JSON)
                    .mediaType("xml", MediaType.APPLICATION_XML)
                    .mediaType("json", MediaType.APPLICATION_JSON);
            // this line alone gave me xhtml for some reason
            // configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
        }
    };
}

(尝试使用 Spring Boot 1.5.x)

https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc

“我们所做的,在这两种情况下:

  • 禁用路径扩展。请注意,青睐并不意味着使用一种方法优先于另一种方法,它只是启用或禁用它。检查的顺序始终是路径扩展、参数、Accept 标头。

  • 启用 URL 参数,但不使用默认参数format,我们将mediaType改为使用。

  • 完全忽略Accept标题。如果您的大多数客户端实际上是 Web 浏览器(通常通过 AJAX 进行 REST 调用),这通常是最好的方法。

  • 不要使用 JAF,而是手动指定媒体类型映射——我们只希望支持 JSON 和 XML。”

于 2017-08-23T15:38:59.307 回答