【问题标题】:Conflict with Accept */* Header when using default ContentType and @RequestMethod.produces使用默认 ContentType 和 @RequestMethod.produces 时与 Accept */* Header 冲突
【发布时间】:2018-02-16 09:48:09
【问题描述】:

我的 Spring 应用程序总是返回 HTTP 406 - 如果我尝试从我的 RestController 获取图像,如果我没有使用正确的扩展名或 Accept-Header,则不可接受。

  • curl http://localhost/images/42 -> 406
  • curl http://localhost/images/42.png -> 200
  • curl http://localhost/images/42 -H 'Accept: image/png' -> 200

这是我的控制器代码:

@RequestMapping(path = "/images/{id}", produces = MediaType.IMAGE_PNG_VALUE)
public void getImage(@PathVariable("id") long id, HttpServletResponse response) throws IOException {
    [...]
}

如果没有请求与方法的结果不兼容的内容类型 (JSON),AFAICT spring 会选择默认的内容类型 (JSON),因此会显示 406。

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.defaultContentType(MediaType.APPLICATION_JSON)
            .favorParameter(true);
}

如果我删除默认 ContentType,则没有 406,但是如果我省略 Accept-Header/file-extension,我的其他方法开始生成 XML/Plain-Text/HTML/stuff(任意)。 (根据控制器中方法的顺序)

有些旧版应用程序不设置标头并依赖 JSON,因此这不是一个选项。


TLDR:我如何告诉 Spring 如果它与我请求的 Controller 方法兼容,它应该只使用默认的 Content-Type?

【问题讨论】:

    标签: spring rest spring-mvc content-type


    【解决方案1】:

    configureContentNegotiation 方法更改为在默认值之后包含一个回退。

    ContentNegotiationConfigurer#defaultContentTypeStrategy(ContentNegotiationStrategy) ContentNegotiationStrategy

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        final List<MediaType> defaultMediaTypes = ImmutableList.of(MediaType.APPLICATION_JSON, MediaType.ALL);
        // First try the default, if the method produces (@RequestMapping#produces) something else use any.
        configurer.defaultContentTypeStrategy(request -> defaultMediaTypes)
                .favorParameter(true);
    }
    

    【讨论】:

    • 哦,是的,你是对的,我没有看到其他方法。我希望这将是 Spring 中的默认行为。如果我有时间,我会在 Spring 上为这项改进开一个 PR。
    猜你喜欢
    • 2015-08-16
    • 1970-01-01
    • 2020-07-13
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多