我的SpringBoot应用程序向外部API发出HTTP请求,所有这些都消耗/生成JSON。默认情况下,我的应用程序使用Jackson进行数据绑定,所有HTTP请求(使用RestTemplate)显然都使用了Accept
的{{1}}和Content-Type
标题。
最近我需要使用Jackson xml数据绑定库(不用于http数据绑定),所以我在应用程序中包含了这个依赖项,似乎SpringBoot决定隐式使用application/json
传出的HTTP请求。
如何在发出HTTP请求时将应用程序配置为默认为JSON,而不必在每个请求的标头中明确设置它?
答案 0 :(得分:1)
只需覆盖并配置WebMvcConfigurerAdapter#configureContentNegotiation(ContentNegotiationConfigurer)
中的默认内容类型,如下所示:
@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
}
答案 1 :(得分:1)
答案主要集中在@RicardoPieper的案例上,但是单个
RestTemplate
案例(来自OP)仍然可以使用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
bean的名字命名的{1}},例如;
RestTemplate
并将拦截逻辑应用于所有这些bean。
@Bean
public RestTemplate jsonTemplate() {
return new RestTemplate();
}
您怎么看? =)它可以在我的演示应用程序上运行,尽管需要某种方式来区分基于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
的{{1}} bean。如果可以创建这种区别,则可以在JSON
方法中添加该逻辑,并且仍然可以使用此思想!