java - 如何为 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 请求映射:
- 颠倒声明映射的顺序。
- 为这两种方法添加@Order 注释(json-ld 值为 1,json 方法值为 2)
- 创建不同的类并将 @Order 注释放在类级别
- 将
Accept=*/*
作为第二个接受头添加到 json-ld 映射确实可以为其提供优先权,但会产生不想要的副作用,即所有接受头都被接受,甚至是不受支持的类型application/xml
,例如。
我能想到的唯一解决方案是创建一个接受两个标头的请求映射方法,然后自己处理接受标头,但我不太喜欢这种解决方案。有没有更好、更简单的方法来优先考虑 json-ld?
解决方案
在对配置自定义 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中的一个错误。
推荐阅读
- c++ - 为什么组合的上限和下限比较总是评估为真?
- c++ - 完美的转发和构造函数
- laravel - 在 Laravel 5.1 环境中创建缓存文件夹以供第三方库编写的最佳位置
- android - 无法检测小于 21 的 API 的 http 错误
- neo4j - 无法使用 neo4j-admin 导入 csv 文件
- python - python argparse CIDR 或带有子网掩码的网络
- security - TLS 证书是否需要通用 SAN
- cs50 - 卡在 cs50 pset3 频率
- unity3d - Blender 与 Unity3D 中的海洋模拟
- python - 如何打印以使用 python 开头的最新文件?