0

To try to understand the spring ecosystem, I'm building some toy projects on varios parts.

I've got a spring-boot-data-rest service working as expected (code here) and I am building a spring-boot and spring-hateoas client to access it (code here)

BUT for some reason I don't understand the client doesn't see the links that the server has.

This is what the JSON the service serves looks like:

{
    "firstName": "Alice",
    "lastName": "Foo",
    "_links": {
        "self": {
            "href": "http://localhost:8080/people/1"
        },
        "person": {
            "href": "http://localhost:8080/people/1"
        }
    }
}

This is the code the client is using to query the service:

    //now use a GET to get it back
    ResponseEntity<Resource<Person>> getResult = rest.exchange(
            "http://localhost:8080/people/1", HttpMethod.GET, null,
            new ParameterizedTypeReference<Resource<Person>>() {
            });

    //check the links on the response
    log.info("getResult "+getResult);
    log.info("getResult.getBody"+getResult.getBody());
    //uh oh, no links...
    log.info("getResult.getLink(\"self\")"+getResult.getBody().getLink("self"));
    log.info("getResult.getLink(\"self\").getHref()"+getResult.getBody().getLink("self").getHref());

And I am using Spring boot 1.4.0.BUILD-SNAPSHOT version for both.

Is this a problem with my code or is this a bug somewhere? Any ideas how to fix it?

afaulconbridge
  • 1,107
  • 9
  • 21

2 Answers2

2

You didn't enable support for HAL. You server uses Spring Data REST, which uses HAL as default. The client, on the other hand, has no idea about HAL. You can add support by adding @EnableHypermediaSupport:

@SpringBootApplication
@EnableHypermediaSupport(type = HypermediaType.HAL)
public class Application {
a better oliver
  • 26,330
  • 2
  • 58
  • 66
  • Thanks for the answer, but unfortunately it doens't work for me - I think that annotation is for use on the server? It did put me on track to a solution anyway though! – afaulconbridge Feb 24 '16 at 11:02
1

As @zeroflagL pointed out, the client as no idea about HAL.

The solution is more complicated and draws on the answer at https://stackoverflow.com/a/23271778/932342 to register an additional HTTPMessageConverter to the RestTemplate to handle "application/hal+json" content.

    RestTemplate rest = new RestTemplate();

    //need to create a new message converter to handle hal+json
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.registerModule(new Jackson2HalModule());
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
    converter.setObjectMapper(mapper);

    //add the new converters to the restTemplate
    //but make sure it is BEFORE the exististing converters
    List<HttpMessageConverter<?>> converters = rest.getMessageConverters();
    converters.add(0,converter);
    rest.setMessageConverters(converters);
afaulconbridge
  • 1,107
  • 9
  • 21
  • The first part is basically what happens when you add `@EnableHypermediaSupport`. But that doesn't affect the `RestTemplate`, only Spring MVC. So unfortunately you are right, you have to do that yourself (yet). – a better oliver Feb 24 '16 at 11:22