What is a convenient way to deserialize JSON (links + inline container) using spring -hateoas?

Colleagues!

We want to write a Rest Client for services that follow the HATEOAS principle. So, we have the following view of HAL + JSON, 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 to be as follows:

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

So, we have a custom representation of resources with a built-in (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 returns Resource.class with zero 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>>>() {}); 

Using the announcements @JsonTypeInfo and @JsonSubTypes , we successfully deserialized our JSON (you can see an example in github ), but we do not want additional types and anotals to be added in our DTO and JSON format.

We see one solution that creates a custom deserializer that can handle this.

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

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

Thanks!

+5
source share

Source: https://habr.com/ru/post/1238095/


All Articles