我的 SpringBoot 应用程序向外部 API 发出 HTTP 请求,所有这些都使用/生成 JSON。默认情况下,我的应用程序使用 Jackson 进行数据绑定(bind),并且所有 HTTP 请求(使用 RestTemplate)显然都使用了 Accept
和 Content-Type
application/json
的标题.
最近我需要使用 Jackson xml 数据绑定(bind)库(不是用于 http 数据绑定(bind)),所以我在应用程序中包含了该依赖项,似乎 SpringBoot 已决定隐式使用 application/xml
对于所有传出的 HTTP 请求。
如何在发出 HTTP 请求时将应用程序配置为默认为 JSON,而无需在每个请求的 header 中显式设置它?
最佳答案
The answer is mostly focused on @RicardoPieper's case, but the single
RestTemplate
case (from OP) can still use this intercept based solution
在我看来,最好是明确的,而不是依赖于
Content-Type
任意设置RestTemplate
.因此,为所有调用设置标题值,例如;HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Post> entity = new HttpEntity<>(post, headers);
ResponseEntity<Post> response = someTemplate.postForEntity(uri, entity, Post.class);
但是对于您的情况,我想出了一个想法,再次进行拦截解决方案,但从更高的角度来看(尽管它仍然有一个假设)
有一个上下文刷新事件的监听器;
@Component
public class MyListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private Map<String, RestTemplate> templates;
public void onApplicationEvent(ContextRefreshedEvent event) {
templates.entrySet().stream()
.filter(this::isJsonBased)
.map(Map.Entry::getValue)
.forEach(template -> template.setInterceptors(Collections.singletonList(new JsonMimeInterceptor())));
}
private boolean isJsonBased(Map.Entry<String, RestTemplate> entry) {
return entry.getKey().toLowerCase().contains("json");
}
}
在这里我得到了所有
RestTemplate
上下文中的bean(包括它们的bean名称,使用 Map autowire feature ),并首先进行过滤,虽然这是假设部分,但我认为有 "json"
以JSON
的名义专注 RestTemplate
bean 类,例如;@Bean
public RestTemplate jsonTemplate() {
return new RestTemplate();
}
并将拦截逻辑应用于所有这些 bean。
public class JsonMimeInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
HttpHeaders headers = request.getHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return execution.execute(request, body);
}
}
你怎么看? =) 它适用于我的演示应用程序,尽管需要某种方式来区分
XML
基于,和 JSON
基于 RestTemplate
bean 。如果您可以创建这样的区别,您可以在 isJsonBased()
中添加该逻辑。方法,仍然使用这个想法!
关于spring - Http 请求的默认 MediaType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47932394/