spring - Http 请求的默认 MediaType

标签 spring spring-boot

我的 SpringBoot 应用程序向外部 API 发出 HTTP 请求,所有这些都使用/生成 JSON。默认情况下,我的应用程序使用 Jackson 进行数据绑定(bind),并且所有 HTTP 请求(使用 RestTemplate)显然都使用了 AcceptContent-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/

相关文章:

java - HTTP 状态 500 - 第 1 行第 129 列附近出现意外标记 : ,

java - 使用 LiquiBase 和 Spring 将大量值(使用 FK)插入数据库

jquery - spring boot中ajax删除方法

azure - Azure 应用服务 API 的 Google Cloud Logging 相当于什么?

java - 通过postman测试上传端点

java - 是否可以在 Spring Repository @Query 注释中动态设置模式?

spring - 依赖注入(inject) - 在运行时决定参数

java - 从 @Configuration 类中的一个方法创建多个 bean

spring - 如何将自定义 ApplicationContextInitializer 添加到 Spring Boot 应用程序?

Java - @ResponseBody 字符串 - 错误 200