在 Spring Boot 中注册自定义 MessageConverter [英] Registering a custom MessageConverter in Spring Boot

查看:72
本文介绍了在 Spring Boot 中注册自定义 MessageConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用返回 text/javascript 内容类型的 RESTful 服务.

由于没有可以在 Spring Boot 中执行此操作的 OOTB HttpMessageConverter,我想注册一个自定义转换器.

我发现的一种方法是通过修改 MappingJackson2HttpMessageConverter 来自定义 RestTemplate 本身:

@Component公共类 CustomRestTemplateProvider {公共 RestTemplate getCustomRestTemplate(MediaType mediaType) {MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();jacksonConverter.setSupportedMediaTypes(Collections.singletonList(mediaType));列表>转换器 = 新的 ArrayList();转换器.add(jacksonConverter);返回新的 RestTemplate(转换器);}}

然后,在我的服务中,只需调用 getCustomRestTemplate(new MediaType("text", "javascript")

根据 Spring Boot 文档 (27.1.2):

所以我创建了一个新的转换器:

@Component公共类 TextJavascriptMessageConverter 扩展 AbstractJackson2HttpMessageConverter {公共 TextJavascriptMessageConverter(ObjectMapper objectMapper) {超级(对象映射器);setTextJavascriptAsSupportedMediaType();}私有无效 setTextJavascriptAsSupportedMediaType() {列表支持的媒体类型 = 新的 ArrayList<>();supportedMediaTypes.add(new MediaType("text", "javascript"));setSupportedMediaTypes(supportedMediaTypes);}}

然后尝试像在文档中一样注册它:

@Configuration公共类应用配置{@豆公共 HttpMessageConverters customConverters() {HttpMessageConverter<对象>转换器 = 新 TextJavascriptMessageConverter(new ObjectMapper());返回新的 HttpMessageConverters(Collections.singletonList(converter));}}

仍然收到一条消息,指出无法提取响应:没有找到适合响应类型 [class example.MyResponsee] 和内容类型 [text/javascript] 的 HttpMessageConverter

我什至尝试扩展 MappingJackson2HttpMessageConverter,但这也不起作用.我错过了什么?此外,为此创建一个新的转换器是一个好习惯,还是可以接受修改现有的转换器(如我在第一个示例中所示)?

解决方案

文档有点模糊,但你应该能够注册你的 HttpMessageConverter bean,它会被适当地添加.

来源:

<块引用>

上下文中存在的任何 HttpMessageConverter bean 都将被添加到转换器列表中

由于您已经将 TextJavascriptMessageConverter 注册为 bean(通过 @Component),您应该能够自动装配 HttpMessageConverters 以访问所有转换器.

虽然最好你可以自动装配一个 RestTemplateBuilder 来为你设置 restTemplate(包括转换器).

示例:

@SpringBootApplication公共类演示应用{@组件公共静态类 TextJavascriptConverter 扩展 AbstractJackson2HttpMessageConverter {公共 TextJavascriptConverter() {//可以使用重载构造函数来设置支持的MediaTypesuper(new ObjectMapper(), new MediaType("text", "javascript"));}}@豆public ApplicationRunner demoRunner(RestTemplateBuilder builder, TextJavascriptConverter javascriptConverter) {返回参数 ->{//可以自动装配 RestTemplateBuilder 以获得合理的默认值(包括转换器)RestTemplate restTemplate = builder.build();//确认你的转换器在那里如果 (restTemplate.getMessageConverters().contains(javascriptConverter)) {System.out.println("我的自定义HttpMessageConverter已注册!");}};}公共静态无效主(字符串 [] args){SpringApplication.run(DemoApplication.class, args);}}

<块引用>

此外,为此创建一个新的转换器是一个好习惯,还是可以接受修改现有的转换器(如我在第一个示例中所示)?

您最好创建自己的转换器,否则您可能会失去对原始媒体类型的支持.

I want to consume a RESTful service that returns text/javascript content type.

Since there is no OOTB HttpMessageConverter which can do this in Spring Boot, I want to register a custom converter.

One way I found to do this is to customize the RestTemplate itself by modifying MappingJackson2HttpMessageConverter:

@Component
public class CustomRestTemplateProvider {
    public RestTemplate getCustomRestTemplate(MediaType mediaType) {
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
        jacksonConverter.setSupportedMediaTypes(Collections.singletonList(mediaType));
        List<HttpMessageConverter<?>> converters = new ArrayList<>();
        converters.add(jacksonConverter);
        return new RestTemplate(converters);
    }
}

Then, in my service, just call getCustomRestTemplate(new MediaType("text", "javascript")

The above solution works fine but I also tried to create a new Converter which handles this one Media Type, according to the Spring Boot Documentation (27.1.2):

So I created a new Converter:

@Component
public class TextJavascriptMessageConverter extends AbstractJackson2HttpMessageConverter {

    public TextJavascriptMessageConverter(ObjectMapper objectMapper) {
        super(objectMapper);
        setTextJavascriptAsSupportedMediaType();
    }

    private void setTextJavascriptAsSupportedMediaType() {
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(new MediaType("text", "javascript"));
        setSupportedMediaTypes(supportedMediaTypes);
    }
}

Then tried to register it like in the documentation:

@Configuration
public class ApplicationConfiguration {

    @Bean
    public HttpMessageConverters customConverters() {
        HttpMessageConverter<Object> converter = new TextJavascriptMessageConverter(new ObjectMapper());
        return new HttpMessageConverters(Collections.singletonList(converter));
    }
}

Still, I get a message that states Could not extract response: no suitable HttpMessageConverter found for response type [class example.MyResponsee] and content type [text/javascript]

I even tried to extend the MappingJackson2HttpMessageConverter, but that didn't work either. What am I missing? Also, is it a good practice to create a new converter for this, or modyfing an existing one (like I shown in the first example) is acceptable?

解决方案

The documentation is a bit hazy but you should be able to just register your HttpMessageConverter bean and it will get added appropriately.

Source:

Any HttpMessageConverter bean that is present in the context will be added to the list of converters

Since you've already registered TextJavascriptMessageConverter as a bean (via @Component) you should be able to just autowire HttpMessageConverters for access to all the converters.

Though preferably you could autowire a RestTemplateBuilder which handles setting up restTemplate for you (including converters).

Example:

@SpringBootApplication
public class DemoApplication {

  @Component
  public static class TextJavascriptConverter extends AbstractJackson2HttpMessageConverter {
    public TextJavascriptConverter() {
      //can use overloaded constructor to set supported MediaType
      super(new ObjectMapper(), new MediaType("text", "javascript"));
    }
  }

  @Bean
  public ApplicationRunner demoRunner(RestTemplateBuilder builder, TextJavascriptConverter javascriptConverter) {
    return args -> {
      //can autowire RestTemplateBuilder for sensible defaults (including converters)
      RestTemplate restTemplate = builder.build();

      //confirm your converter is there
      if (restTemplate.getMessageConverters().contains(javascriptConverter)) {
        System.out.println("My custom HttpMessageConverter was registered!");
      }
    };
  }

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
}

Also, is it a good practice to create a new converter for this, or modyfing an existing one (like I shown in the first example) is acceptable?

You're probably better off creating your own converter otherwise you risk dropping support for the original media type(s).

这篇关于在 Spring Boot 中注册自定义 MessageConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆