Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering a custom MessageConverter in Spring Boot

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?

like image 888
RK1 Avatar asked Oct 26 '25 07:10

RK1


1 Answers

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).

like image 76
cdub Avatar answered Oct 27 '25 20:10

cdub