Search code examples
spring-bootspring-hateoas

Spring Hateoas: When consuming with RESTTemplate then content is always empty


I have an endpoint which produces hateoas resources:

@GetMapping()
public ResponseEntity<PagedModel<EntityModel<Content>>> getContent(
    @RequestParam(defaultValue = "0") final Integer page,
    @RequestParam(defaultValue = "10") final Integer size) {
        return ResponsEntity
            .ok()
            .body(service.getContent(page, size));
}

When I call this endpoint using a browser I get the following result:

{
    "_embedded" : {
        "contents": [
            ...,
            ...
        ]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/contents?page=0&size=10"
        }
    },
    "page": {
        "size": 10,
        "totalElements": 2,
        "totalPages": 1,
        "number": 0
    }
}

That is fine. But when I use another spring service to consume the endpoint using a rest template:

ResponseEntity response = restTemplate.exchange(
    url, 
    GET, 
    null,
    new ParameterizedTypeReference<PagedModel<EntityModel<Content>>>() {}));

LOG.info(response);

I get the following output:

<200, PagedResource { content: [], metadata: Metadata { number: 0, total pages: 1, total elements: 2, size: 10}, links: } ...

The content is always empty.

What do I need to do to be able to deserialize the PagedResource correctly?


Solution

  • Had to add the following configuration:

    @Configuration
    public class ServiceConfiguration {
    
      @Bean
      public ObjectMapper objectMapper() {
        final ObjectMapper objectMapper = new ObjectMapper();
    
        objectMapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.registerModule(new Jackson2HalModule());
    
        return objectMapper;
      }
    
      @Bean
      public MappingJackson2HttpMessageConverter converter() {
        final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    
        converter.setSupportedMediaTypes(singletonList(HAL_JSON));
        converter.setObjectMapper(objectMapper());
    
        return converter;
      }
    
      @Bean
      public RestTemplate restTemplate(final RestTemplateBuilder builder) {
        return builder.messageConverters(converter()).build();
      }
    }