【问题标题】:Spring mvc : Changing default Response format from xml to jsonSpring mvc:将默认响应格式从 xml 更改为 json
【发布时间】:2017-04-23 12:18:51
【问题描述】:

我已经解决了其他类似的问题,但对我没有任何帮助。

我所有的 API 都返回 JSON 作为响应默认情况下

由于一些 XML API,我不得不添加 jackson-xml

    <dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>

现在默认为“不带接受头”所有响应都是 XML

我希望将 JSON 作为默认响应格式

如文档中所述:

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

我实现了以下配置:

@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);
    }

案例 1: 如果我创建 ignoreAcceptHeader(true),那么一切都是 JSON,甚至 XML API 返回 JSON。

案例 2:ignoreAcceptHeader(false) 为默认值时为 XML。

我忘记提及我的 API 是这样的:

@RequestMapping(value = "/getXml", method = RequestMethod.GET)
public ResponseEntity<String> getXml( HttpServletRequest request)
        throws JAXBException {
    return returnXml();
}

我在这里很迷茫,我想要的只是默认(没有 AcceptHeader)应该是 JSON。 (API 将 XML 作为字符串返回)

当 Accept Header : "Application/xml" 被定义时,响应应该是 XML。

任何建议都会有很大帮助。

谢谢。

【问题讨论】:

  • 根据配置,您可以使用'mediaType'参数控制返回媒体类型。您是否尝试过 /getXml?mediaType=xml
  • @Stan : 不,我无法更改 RequestMapping,但我仍然会尝试查看结果
  • 这与请求映射注释无关,据我了解,您对 Spring 使用 .parameterName("mediaType") 语句使用此参数检查媒体类型,因此您的服务器端没有更改跨度>
  • @Stan : 它起作用了:) :) 但是我必须将新的 URL 传达给客户?或者我可以在收到请求后操纵 URL?
  • @Stan :如果我没记错,那么添加类似 response.setContentType(MediaType.APPLICATION_XML_VALUE);在 API 中应该是一样的吧?

标签: spring spring-mvc spring-boot


【解决方案1】:

由于您已将 ignoreAcceptHeader 设置为 true 并将喜爱路径扩展设置为 false,因此 spring 将依赖其他替代方案进行内容协商。意味着它将查看您已配置 XML 和 JSON 的 URL 参数

所以@stan 指出 /getXml?mediaType=xml 应该返回 xml 响应,否则它将默认为 json(defaultContentType(MediaType.APPLICATION_JSON))

【讨论】:

  • 感谢您的回复,但我已经在做这样的事情了:contentTypeList.add(MediaType.APPLICATION_XML_VALUE); headers.put("内容类型", contentTypeList);我希望它发送没有“?mediatype = xml”的XML
  • 但这并没有发生。
【解决方案2】:

一般来说,如果你想获得 json 响应,你需要一个 jackson-databind 模块:

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>${json-jackson-version}</version> 
</dependency> 

然后你必须在你的配置中定义一个MappingJackson2HttpMessageConverter

@Configuration
@EnableWebMvc
public class WebAppMainConfiguration extends WebMvcConfigurerAdapter {

    @Override 
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
        converters.add(new MappingJackson2HttpMessageConverter());

        [..] 
        super.configureMessageConverters(converters); 
    }

    [...]
}

在您的情况下,您可以实现自己的AbstractGenericHttpMessageConverter,以便您可以根据媒体类型在不同的具体转换器之间切换此转换器。

检查方法AbstractGenericHttpMessageConverter#writeInternal(..)

【讨论】:

    【解决方案3】:

    对我来说,添加

    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
            configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
        }
    
    }
    

    解决了问题。

    如果请求中没有 Accept 标头,现在默认情况下所有 RestControllers 都返回 JSON。 此外,如果 Accept: application/xml 标头被传递,则结果为 XML。

    另外,值得一读:https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc

    【讨论】:

    • 只是一个细节:在 Spring Boot 应用程序中,您的 @Configuration 类不应包含 @EnableWebMvc 注释 (source)。它可能会阻止其他东西工作,例如 springfox-swagger-ui html 页面。
    • @PauloMerson 是的,你完全正确!我会从答案中删除它以防止混淆任何读者,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 2016-07-04
    • 2020-10-18
    • 2017-08-08
    • 2016-09-04
    • 1970-01-01
    • 2017-03-08
    相关资源
    最近更新 更多