首页 > 解决方案 > 如何为 Spring-Boot 请求映射方法设置优先级

问题描述

我有一个带有 RestController 的 Spring-Boot (v2.0.2) 应用程序,它有 2 种方法,它们的区别仅在于 Accept 标头。代码的简化版本是这样的:

@RestController
@RequestMapping("/myapp")
public class FooController {

    @GetMapping(value = "/foo/{id}", headers = "Accept=application/json", produces = "application/json;charset=UTF-8")
    public ResponseEntity<String> fooJson(@PathVariable id) {
        return foo(pageId, true);
    }

    @GetMapping(value = "/foo/{id}", headers = "Accept=application/ld+json", produces = "application/ld+json;charset=UTF-8")
    public ResponseEntity<String> fooJsonLd(@PathVariable id) {
        return foo(pageId, false);
    }

    private ResponseEntity<String> foo(String id, boolean isJson) {
        String result = generateBasicResponse(id);
        if (isJson) {
            return result
        }
        return addJsonLdContext(result);
    }

这工作正常。如果我们发送一个带有接受头的请求,例如application/json;q=0.5,application/ld+json;q=0.6例如,它将返回一个 json-ld 响应。

我的问题是,如果我们发送的请求没有接受标头、空的接受标头或通配符*/*,那么默认情况下它将始终返回 json 响应,而我希望默认响应为 json-ld。

我尝试了各种方法来使 json-ld 请求映射优先于 json 请求映射:

我能想到的唯一解决方案是创建一个接受两个标头的请求映射方法,然后自己处理接受标头,但我不太喜欢这种解决方案。有没有更好、更简单的方法来优先考虑 json-ld?

标签: javaspring-bootspring-restcontrollerrequest-mappingcontent-negotiation

解决方案


在对配置自定义 MediaTypes 的这个问题进行了更多搜索之后,我找到了正确的方向。WebMvcConfigurerAdapter(Spring 3 或 4)或 WebMvcConfigurer(Spring 5)允许您设置默认媒体类型,如下所示:

public static final String MEDIA_TYPE_JSONLD  = "application/ld+json";

@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.valueOf(MEDIA_TYPE_JSONLD));
    }
}

这对于没有或为空的接受标头的请求以及accept: */*. 但是,当您将不支持的类型与通配符结合使用时,例如accept: */*,text/plain它将返回 json 而不是 json-ld!?我怀疑这是Spring中的一个错误。


推荐阅读