7

colleagues!

We want to write Rest Client to service which follow the HATEOAS principle. So we have the following HAL+JSON representation and we want to deserialize it using spring-hateoas :

{
    "id": "1",
    "title": "album title",
    "artistId": "1",
    "stockLevel": 2,
    "_links": {
        "self": {"href": "http://localhost:8080/rest/albums/1"},
        "artist": {"href": "http://localhost:8080/rest/artist/1"}
    },
    "_embedded": {
        "albums": [{ //can be array or object
            "id": "1",
            "title": "album title",
            "artistId": "1",
            "stockLevel": 2,
            "_links": {
                "self": {"href": "http://localhost:8080/rest/albums/1"}
            }
        }],
        "artist": { //can be array or object
            "id": "1",
            "name": "artist name",
            "_links": {
                "self": {"href": "http://localhost:8080/rest/artist/1"}
            }
        } //.... 
    }
}

We expected the java object like this:

HalResource {
    Resource<Album> //entity 
    List<Link> // _links
    List<Resource<BaseEntity>>{ //_embedded
        Resource<Album>
        Resource<Artist>
         ....
    } 
}

So we have custom resource representation with embedded(list of resources) and entity(single resource):

@XmlRootElement(name = "resource")
public class HalResource<EntityType, EmbeddedType> extends Resources<EmbeddedType> {

    @JsonUnwrapped
    private EntityType entity;

    public HalResource() {
    }

    public HalResource(Iterable<EmbeddedType> content, Link... links) {
        super(content, links);
    }

    public EntityType getEntity() {
        return entity;
    }

    public void setEntity(EntityType entity) {
        this.entity = entity;
    }
}

DTO classes:

public abstract class BaseEntity{}

@XmlRootElement(name = "album")
public class Album extends BaseEntity {  
    private String id;
    private String title;
    private String artistId;
    private int stockLevel;

    // getters and setters...
}

@XmlRootElement(name = "artist")
public class Artist extends BaseEntity {
    private String id;
    private String name;

    // getters and setters...
}

And we want to get something like this, where Entity will be Artist or Album, but HalResourcesDeserializer return Resource.class with null content.

    HalResource<Album, Resource<Entity>> resources = 
    restClient.getRootTarget().path("albums/1").queryParam("embedded", true).request().accept("application/hal+json")
    .get(new GenericType<HalResource<Album, Resource<Entity>>>() {});

By using @JsonTypeInfo and @JsonSubTypes anotations we successfully deserialized our JSON(you can see the example on the github), but we don't want to have some additional type filds and anotattions in our DTO and JSON format.

We see one solution that is create a custom deserializer which can processing that.

So the question is: What is the convenient way to deserialize our JSON(links + embedded container) using spring-hateoas?

We use spring-hateoas 0.16v(but we tried 0.19v) and glassfish jersey 2.22.1

Thank you!

  • From the project description: _"Spring HATEOAS provides some APIs to ease **creating** REST representations"_ (emphasis mine). – a better oliver Dec 15 '15 at 11:11
  • Ok, but Spring-hateoas have some deserializer which know how to deserialize links, resources and embedded container. – V. Spachynskyi Dec 15 '15 at 17:42
  • 2
    If you are referring to `Jackson2HalModule` the documentation states _"Jackson 2 module implementation to **render** ..."_, And it's an implementation detail. The documentation doesn't mention deserialization either. Spring HATEOAS also serves as library for Spring Data REST which may explain some of the additional functionality. But as a consumer of Spring HATEOAS you should regard it as write-only until the documentation tells you otherwise. Maybe @OliverGierke reads this question and has to say something more encouraging. – a better oliver Dec 17 '15 at 09:15

0 Answers0