Http请求的默认MediaType

时间:2017-12-21 20:37:43

标签: spring spring-boot

我的SpringBoot应用程序向外部API发出HTTP请求,所有这些都消耗/生成JSON。默认情况下,我的应用程序使用Jackson进行数据绑定,所有HTTP请求(使用RestTemplate)显然都使用了Accept的{​​{1}}和Content-Type标题。

最近我需要使用Jackson xml数据绑定库(不用于http数据绑定),所以我在应用程序中包含了这个依赖项,似乎SpringBoot决定隐式使用application/json传出的HTTP请求。

如何在发出HTTP请求时将应用程序配置为默认为JSON,而不必在每个请求的标头中明确设置它?

2 个答案:

答案 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方法中添加该逻辑,并且仍然可以使用此思想!