3

I want to create a custom of HttpMessageConverter using Rest, Json, Spring Boot 1.2.3 and Spring 4, However my custom HTTPMessageConverter its' never called.

I have preformed the following steps :

1: Created a class that extends AbstractHttpMessageConverter

@Component
public class ProductConverter extends AbstractHttpMessageConverter<Employee>   {

public ProductConverter() {
     super(new MediaType("application", "json", Charset.forName("UTF-8")));     
     System.out.println("Created ");
}

@Override
protected boolean supports(Class<?> clazz) {
    return false;
}

@Override
protected Employee readInternal(Class<? extends Employee> clazz,
        HttpInputMessage inputMessage) throws IOException,
        HttpMessageNotReadableException {
    InputStream inputStream =  inputMessage.getBody();
    System.out.println("Test******");
    return null;
}

@Override
protected void writeInternal(Employee t,
        HttpOutputMessage outputMessage) throws IOException,
        HttpMessageNotWritableException {
    // TODO Auto-generated method stu   
}

}

2: I create a configuration class to register HTTPMessageConverters

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{  
   @Override
   public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
     System.out.println("Configure Message Converters");
     converters.add(new ProductConverter());
     super.configureMessageConverters(converters);
     //super.extendMessageConverters(converters);
    }
 }

3: The rest class method

@RequestMapping(value="/{categoryId}" ,method=RequestMethod.POST, consumes="application/json")
@PreAuthorize("permitAll")
public ResponseEntity<ProductEntity>  saveProduct(@RequestBody Employee  employee , @PathVariable Long categoryId) {

    logger.log(Level.INFO, "Category Id: {0}" , categoryId);

    ResponseEntity<ProductEntity> responseEntity =
            new ResponseEntity<ProductEntity>(HttpStatus.OK);
    return responseEntity;
}

My Custom HTTPMessageCoverter it's created but is never called ? Is there a configuration or step I'm missing ? any input or advice is appreciated.


After overriding the (AbstractHttpMessageConverter) class methods, I found out there's two annotations for achieving polymorphism @JsonTypeInfo and @JsonSubTypes. For anyone who wants achieve polymorphism can use these two annotations.

Kamal
  • 1,476
  • 1
  • 13
  • 21

1 Answers1

3

I believe you want to configure these message converters using the configureMessageConverters method in a configuration class that extends WebMvcConfigurerAdapter. I've done this myself with a converter for CSV content. I've included that code below. This link shows an example as well. This link may also be helpful. It seems like with Spring configuration it is not always clear on the best place to configure things. :) Let me know if this helps.

@Configuration
public class ApplicationWebConfiguration extends WebMvcConfigurerAdapter {
     @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(new CsvMessageConverter());
    }
}

You will also need top modify your supports() method to return true for classes supported by the converter. See the Spring doc for AbstractHttpMessageConverter supports method.

Community
  • 1
  • 1
Rob Baily
  • 2,770
  • 17
  • 26
  • Thanks @Rob. I have made the changes but my custom converter still never called. From the logs I could see the custom cover is created and configureMessageConverters Method called. – Kamal Jun 11 '15 at 06:53
  • In looking at your code a little more closely I see that your supports() method always returns false. It will need to return true for the class you want to convert. One other thing, assuming you have Jackson in your class path you should not need to create a custom converter for JSON as the Jackson converters are included when it is in the classpath per http://docs.spring.io/spring/docs/current/spring-framework-reference/html/remoting.html#rest-message-conversion. You may also want to look as this Spring guide http://spring.io/guides/tutorials/bookmarks/ on REST. – Rob Baily Jun 11 '15 at 11:59
  • Thanks @Rob, it was the supports method. I know I shouldn't create a custom converter but I want to experiment and see if i can return Sub-Product class that belongs to category.. – Kamal Jun 11 '15 at 12:39
  • `@SpringBootApplication public class FooApplication extends WebMvcConfigurerAdapter { public static void main(String[] args) { SpringApplication.run(FooApplication.class, args); } @Override public void configureMessageConverters(List> converters) { super.configureMessageConverters(converters); converters.add(new FastJsonHttpMessageConverter()); } } ` why this code does not work – zhuguowei Dec 10 '15 at 03:03
  • @zhuguowei It is virtually impossible to say why yours does not work without more information and you also need to define what "does not work" means. I would suggest creating a new question with more detailed information that we can take a look at. Be sure to include the versions you are using the behavior you see, etc. – Rob Baily Dec 10 '15 at 13:18
  • Thanks! Please see http://stackoverflow.com/questions/34172163/spring-boot-how-to-custom-httpmessageconverter – zhuguowei Dec 11 '15 at 02:58
  • If you have a list of converters, how do you know which converter is actually used for a specific `ResponseEntity`? Today I met this problem, I return a `File` object, and wish it could be handled by exactly one of the converters (a list), but actually it is handled by a different one. The whole response thereafter is funny. – Tiina Dec 18 '17 at 07:04
  • @Tiina that is probably best asked as a separate question. AFAIK there is no deterministic way but I am not sure. – Rob Baily Dec 18 '17 at 13:20