在 Spring Boot 中注册自定义 MessageConverter [英] Registering a custom MessageConverter in Spring Boot
问题描述
我想使用返回 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")
所以我创建了一个新的转换器:
@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.
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屋!