Spring Data Rest - _links
Solution 1
Also with mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
use @JsonIgnoreProperties(ignoreUnknown = true)
on every Entity:
@Entity
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
...
}
Solution 2
For Spring-boot 1.3.3 the method exchange() for List is working
public void test1() {
RestTemplate restTemplate = restTemplate();
ParameterizedTypeReference<PagedResources<User>> responseTypeRef = new ParameterizedTypeReference<PagedResources<User>>() {
};
String API_URL = "http://localhost:8080/api/v1/user"
ResponseEntity<PagedResources<User>> responseEntity = restTemplate.exchange(API_URL, HttpMethod.GET,
(HttpEntity<User>) null, responseTypeRef);
PagedResources<User> resources = responseEntity.getBody();
Collection<User> users = resources.getContent();
List<User> userList = new ArrayList<User>(users);
System.out.println(userList);
}
private RestTemplate restTemplate() {
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);
List<HttpMessageConverter<?>> converterList = new ArrayList<HttpMessageConverter<?>>();
converterList.add(converter);
RestTemplate restTemplate = new RestTemplate(converterList);
return restTemplate;
}
Related videos on Youtube
APD
Updated on June 04, 2022Comments
-
APD almost 2 years
Edit 14/08/14 13:29
My next conclusion is that the hal+json format produced from my @RepositoryRestResource CrudRepository is incorrect.
The tutorial (http://spring.io/guides/gs/accessing-data-rest/) shows the output of a hypermedia Rest JPA entity as: (please note there is no "rel" element, and "links" is not an array)
{ "_links" : { "people" : { "href" : "http://localhost:8080/people{?page,size,sort}" } } }
However, the reference docs (http://docs.spring.io/spring-data/rest/docs/1.1.x/reference/html/intro-chapter.html) show that the output should be:
{ "links" : [ { "rel" : "customer", "href" : "http://localhost:8080/customer" }, { "rel" : "profile", "href" : "http://localhost:8080/profile" } }
Does anyone know why this is?
=====================================
Edit 14/08/14: I have taken my debugging a step further. By providing my own implementation of a org.springframework.hateoas.ResourceSupport class, which inspects the json for "_links" rather than "links" I get a step further. The error is:
"Can not deserialize instance of java.util.ArrayList out of START_OBJECT token ..... through reference chain: com.ebs.solas.admin.test.SolicitorDTO[\"_links\"]"
This is because the org.springframework.hateoas.ResourceSupport class seems to require that the links attribute be a json array. And by default the json+hal output produced by Spring Data for a Rest Entity does not produce an array (there are no square brackets):
"_links" : { "self" : { "href" : "http://localhost:9090/solas-admin-data-api/solicitorFirms/Fxxx" }, "solicitors" : { "href" : "http://localhost:9090/solas-admin-data-api/solicitorFirms/Fxxx/solicitor } }
Hopefully someone from the Spring forums could help me here.
==============================================
please see an outline of my Spring Data repository code:
@RepositoryRestResource public interface SolicitorFirmRepository extends CrudRepository<SolicitorFirm, String> { } @Entity @RestResource @Table(name="XXXX", schema = "XXX") public class SolicitorFirm implements Serializable { }
This successfully generates the following hateoas resource:
{ "firmNumber" : "FXXXX", "solicitorType" : "r", "companyName" : "XXXX", "address1" : "XXXX", "address2" : "XXX", "address3" : "XXX", "address4" : null, "phoneNumber" : "XXXXX", "faxNumber" : "XXXXX", "county" : "OY", "_links" : { "self" : { "href" : "http://localhost:9090/solas-admin-data-api/solicitorFirms/XXXX" }, "solicitors" : { "href" : "http://localhost:9090/solas-admin-data-api/solicitorFirms/XXXX/solicitors" } }
HOWEVER, when i define a DTO for clientside/controller use:
import org.springframework.hateoas.ResourceSupport; public class SolicitorFirmDTO extends ResourceSupport { ..... }
and use the following code
RestTemplate rt = new RestTemplate(); String uri = new String("//xxxxx:9090/solas-admin-data-api/solicitors/Sxxxxx"); SolicitorFirmDTO u = rt.getForObject(uri, SolicitorFirmDTO.class, "SXXXX");
I get the following error:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "_links" (class com.ebs.solas.admin.test.SolicitorFirmDTO), not marked as ignorable (7 known properties: xx])
For some reason the json produced by Spring Data Rest adds the entity links under
_links
while the HATEOAS resource superclass expectslinks
?Can any one help? is this a version issue or do I need some extra configuration to map
_links
tolinks
I have tried
MappingJackson2HttpMessageConverter
and various media typesapplication/json+hal
to no avail.-
Chris DaMour over 9 yearsThe output is HAL+JSON but your input is expecting just Spring's JSON data type. Do you need to talk HAL? Do you have @enablehypermediasupport annotation somewhere?
-
Chris DaMour over 9 yearsasking again..do you need to talk HAL? if you do..then your client parser needs to know how to deserialize it.
-
APD over 9 yearsSorry I will be more specific. yes I do need HAL and obviously the client must be able to deserialize hal+json. If you look at the code I have posted then to the best of my knowledge I have configured/developed my client side code to do exactly that. It creates a Jackson2HalModule object mapper, a MappingJackson2HttpMessageConverter(with application/hal+json media type set) and configures both on the RestTemplate object. thanks
-
-
Leonard Brünings over 9 yearsYou should edit your question instead of posting an answer which is just a reply to another answer/comment.
-
APD over 9 yearssorry, my first question on stackoverflow. will do in future
-
Florian Schaetz almost 8 yearsThanks. The Converter for
application/hal+json
seems to do the trick just fine, otherwise RestTemplate isn't able to parse the whole "_link" thing.