0

In my Spring Boot application, I have assigned the HAL object-mapper to MappingJackson2HttpMessageConverter. This is because my custom media-types end with +json and end up being recognized by the default converter. The custom MappingJackson2HttpMessageConverter instance registered by Spring HATEOAS only recognizes application/hal+json. My custom media-types are of the form application/vnd.service.entity.v1.hal+json, which are recognized by the default instance (because it supports application/json and application/*+json). However, the default instance does not serialize links properly into the HAL convention. I have been able to get around it by registering the mapper like so:

@Bean
public HttpMessageConverters customConverters() {
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(Arrays.asList(
            new MediaType("application", "json", Charset.defaultCharset()),
            new MediaType("application", "*+json", Charset.defaultCharset()),
            new MediaType("application", "hal+json")
    ));

    ObjectMapper halObjectMapper = beanFactory.getBean(HAL_OBJECT_MAPPER_BEAN_NAME, ObjectMapper.class);
    converter.setObjectMapper(halObjectMapper);

    return new HttpMessageConverters(converter);
}

There is a concern that I am now polluting regular JSON serialization/deserialization with HAL concerns, but I cannot think of any other way (short of explicitly specifying every single custom media-type I use) to do this. Thoughts?

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • I can tell you from my experience the HAL serializer is kinda hacked in there and doesn't play nice with spring boot at all. We remove the built in one and register our own based on the built in one. What specifically is the built in one doing wrong with links? – Chris DaMour Dec 19 '14 at 07:46
  • When you include Spring HATEOAS you get HAL support out of the box. And it doesn't depend on the media type. I don't understand what you are trying to achieve. Which functionality do you need that's not supported by Spring HATEOAS? – a better oliver Dec 19 '14 at 10:48
  • @zeroflagL Yes, it gives you HAL support out of the box, but you have to enable the serialization in HAL format specifically by using an annotation. But even with that annotation, media-types like `application/vnd.service.entity.v1.hal+json` are recognized by the standard JSON converter because it recognizes `application/*+json` whereas the HAL converter only recognizes `application/hal+json`. So you don't links serialized properly in HAL+JSON convention. – Vivin Paliath Dec 19 '14 at 16:12
  • @ChrisDaMour When you use `@EnableHypermediaSupport(type=EnableHypermediaSupport.HypermediaType.HAL)` for HAL+JSON serialization, you get links in HAL format where the `_links` property has rels as keys. Without this, you get an array of objects where the rel is a property. So the problem is that even with the annotation, custom media-types aren't recognized by the standard converter that comes with Spring HATEOAS. So you have to override the standard JSON converter to have the HAL mapper. – Vivin Paliath Dec 19 '14 at 16:15
  • Sorry, I still don't understand the problem. Let's say I have a controller method to get an entity of the type `Person`, with the media type `application/vnd.mycompany.person+json`. I would have a DTO that exposes links, probably extending `ResourceSupport`. There's is nothing to do - except for adding `@EnableHypermediaSupport` - to have the links properly serialized according to the HAL format. – a better oliver Dec 19 '14 at 19:04
  • @zeroflagL that's the problem. When you have `application/vnd.mycompany.person+json`, it's recognized by the default converter which exposes the links property as an array of objects. Whereas if your media-type was simply `application/hal+json` it would be picked up by Spring HATEOAS' converter which would serialize the links correctly in JSON; the converter registered by Spring HATEOAS won't recognize your custom media-type. – Vivin Paliath Dec 19 '14 at 19:49
  • Now I see your point, but as a matter of fact what you want **does** work out of the box. Also Spring HATEOAS doesn't register its own converter. Links are serialized to the HAL format by the `HalLinkListDeserializer`, and that will be done automatically if your DTO is assignable to `ResourceSupport`. The media type doesn't really matter as long as it's JSON. – a better oliver Dec 20 '14 at 10:27
  • @zeroflagL Can you describe the configuration/setup you used to get custom media-types recognized by Spring HATEOAS? My DTO's already extend `ResourceSupport`, but as I mentioned before, when it sees `+json`, it gets serialized by the default mapper because Spring HATEOAS' mapper only recognizes `application/hal+json`. So yes, the links do get serialized by the default mapper, but they are not serialized according to the HAL convention. – Vivin Paliath Jan 07 '15 at 20:13

0 Answers0