我的SpringBoot应用程序向外部app发出HTTP请求,所有这些app都使用/生成JSON。默认情况下,我的应用程序使用Jackson进行数据绑定,所有HTTP请求(使用RestTemplate)显然都使用了application/json的Accept和Content-Type头。
最近,我需要使用Jackson数据绑定库(而不是用于http数据绑定),因此我在应用程序中包含了该依赖项,而且SpringBoot似乎已经决定对所有传出的HTTP请求隐式使用application/xml。
在发出HTTP请求时,我如何将应用程序配置为默认为JSON,而不必在每个请求的头中显式设置它?
发布于 2019-09-20 06:52:25
答案主要集中在@RicardoPieper的案例上,但单一的
RestTemplate案例(来自OP)仍然可以使用https://stackoverflow.com/questions/43590448/set-default-content-type-header-of-spring-resttemplate
在我看来,最好是显式的,而不是依赖于任何RestTemplate中的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()方法中添加这个逻辑,并且仍然使用这个思想!
发布于 2017-12-21 23:20:50
只需覆盖和配置WebMvcConfigurerAdapter#configureContentNegotiation(ContentNegotiationConfigurer)中的默认内容类型,如下所示:
@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
}https://stackoverflow.com/questions/47932394
复制相似问题