Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data Rest: how to register a custom conversionService with custom Converter<Entity, Resource>?

There is something that is not enough clear in this part of Spring Data Rest documentation:

The Spring Data REST exporter executes any discovered ResourceProcessor`s before it creates the output representation.

For what I have noticed, it's true: ResourceProcessor are invoked during the handling of the request, after the completion of RepositoryEntityController respective method.

It does this by registering a Converter<Entity, Resource> instance with an internal ConversionService.

I don't understand when it is used this Converter<Entity,Resource>.

This is the component responsible for creating the links to referenced entities (e.g. those objects under the _links property in the object’s JSON representation). It takes an @Entity and iterates over its properties, creating links for those properties that are managed by a Repository and copying across any embedded or simple properties.

Sure? I noticed that the _links to referenced entities are created in the RepositoryEntityController. I didn't see any other component that builds those links: no ConversionService or Converter are involved.

If your project needs to have output in a different format, however, it’s possible to completely replace the default outgoing JSON representation with your own. If you register your own ConversionService in the ApplicationContext and register your own Converter, then you can return a Resource implementation of your choosing.

I don't undestand how is possible to do that.

I have tried to do exactly what is written in the documentation: I have registered my own ConversionService in the ApplicationContext and my own Converter.

I have registered the ConversionService in a custom class that extends RepositoryRestMvcConfiguration:

@Configuration
public class RepositoryConfiguration extends RepositoryRestMvcConfiguration {

    @Autowired
    AuthorConverter authorConverter;

    @Bean(name="conversionService")
    public ConversionService getConversionService() {       
        DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
        conversionService.addConverter(authorConverter);
        return conversionService;
    }

    @Override
    public DefaultFormattingConversionService defaultConversionService() {
        return (DefaultFormattingConversionService) getConversionService();
    }
}

This is the AuthorConverter:

@Component
public class AuthorConverter implements Converter<Author, Resource> {

    @Override
    public Resource convert(Author source) {
        System.out.println("convert method of class AuthorConverter");
        // still to be implemented
        return null;
    }

}

But the converter is never used: if I go the the /authors url, the JSON is solved as the standard representation, and the "convert" method of the converter is never invoked.

I want to understand (possibly with a working example) how have a custom converter that's being involved in the process of the output representation.

Thanks.

like image 950
Alessandro C Avatar asked Nov 08 '22 11:11

Alessandro C


1 Answers

Does this article help? Source: http://www.baeldung.com/spring-httpmessageconverter-rest

"We can customize the message converters by extending the WebMvcConfigurerAdapter class and overriding the configureMessageConverters method:

@EnableWebMvc
@Configuration
@ComponentScan({ "org.baeldung.web" })
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(
      List<HttpMessageConverter<?>> converters) {

        messageConverters.add(createXmlHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());

        super.configureMessageConverters(converters);
    }
    private HttpMessageConverter<Object> createXmlHttpMessageConverter() {
        MarshallingHttpMessageConverter xmlConverter = 
          new MarshallingHttpMessageConverter();

        XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
        xmlConverter.setMarshaller(xstreamMarshaller);
        xmlConverter.setUnmarshaller(xstreamMarshaller);

        return xmlConverter;
    }
}
like image 162
Robert Avatar answered Nov 15 '22 07:11

Robert