Json returned unexpectedly, has "links" written as "_links", and the structure is different in Spring hateoas

As the name says, I have a Product resource object that extends ResourceSupport . However, the answers I get have the property β€œ_links” instead of β€œlinks” and have a different structure.

 { "productId" : 1, "name" : "2", "_links" : { "self" : { "href" : "http://localhost:8080/products/1" } } } 

Based on the HATEOAS Reference , the following is expected:

 { "productId" : 1, "name" : "2", "links" : [ { "rel" : "self" "href" : "http://localhost:8080/products/1" } ] } 

Was it intended? Is there a way to change it or to lyse a β€œlink” if not a structure?

I added selfLink through the following snippet:

 product.add(linkTo(ProductController.class).slash(product.getProductId()).withSelfRel()); 

I am using spring boot with the following build file:

 dependencies { compile ("org.springframework.boot:spring-boot-starter-data-rest") { exclude module: "spring-boot-starter-tomcat" } compile "org.springframework.boot:spring-boot-starter-data-jpa" compile "org.springframework.boot:spring-boot-starter-jetty" compile "org.springframework.boot:spring-boot-starter-actuator" runtime "org.hsqldb:hsqldb:2.3.2" testCompile "junit:junit" } 
+6
source share
5 answers

If you have a HAL, it will be selected for you using spring boot (and "_links" is what you get with the HAL). You must be able to @EnableHypermediaSupport manually override the default values.

+5
source

Spring Now loading (version = 1.3.3.RELEASE) has a property that controls the output JSON format of PagedResources .

Just add the following configuration to the application.yml file:

 spring.hateoas.use-hal-as-default-json-media-type: false 

if you need a conclusion similar (based on a question):

 { "productId" : 1, "name" : "2", "links" : [ { "rel" : "self" "href" : "http://localhost:8080/products/1" } ] } 

Edited by:

By the way, you only need the @EnableSpringDataWebSupport annotation @EnableSpringDataWebSupport this way.

+4
source

Another option is to disable the automatic hypermedia tuning function (here's how to do it in one of the spring-boot + REST examples here ):

 @EnableAutoConfiguration(exclude = HypermediaAutoConfiguration.class) 

As far as I know, HypermediaAutoConfiguration doesn't actually do anything except to configure the HAL, so it should be great to disable it.

+2
source

I noticed that the problem occurs, at least when you try to return an extends object. A ResourseSupport vs object object that contains extends ResourseSupport. You can even return List or Array of the object (s), which extends ResourseSupport and has the same effect. See an example:

 @RequestMapping(method = GET, value = "/read") public NfcCommand statusPayOrder() { return generateNfcCommand(); } 

have the answer:

 { "field": "123", "_links": { "self": { "href": "http://bla_bla_bla_url" } } } 

When trying to wrap as a List:

 @RequestMapping(method = GET, value = "/read") public List<NfcCommand> statusPayOrder() { return Arrays.asList(generateNfcCommand()); } 

I get:

 [ { "field": 123 "links": [ { "rel": "self", "href": "http://bla_bla_bla_url" } ] } ] 

Changing the structure of the answer is not the right decision, but we can try to continue further.

0
source

I'm sure you are using Spring data with the @RepositoryRestResource annotation

 @RepositoryRestResource public interface XX extends CrudRepository<AA, String> 

If you want to remove the default HAL behavior, you can add the following annotation parameter

 @RepositoryRestResource(exported = false) public interface XX extends CrudRepository<AA, String> 

Above is the Spring Data REST configuration to show only rest endpoints for resources in the parent project, without explicitly annotating each repository in the dependency project.

According to the document

Hiding specific repositories, query methods, or fields You might not need a specific repository, the query method in the repository, or the field of your object for export. Examples include hiding fields such as a password on a user object or similar sensitive data. To tell the exporter not to export these elements, annotate them with @RestResource and set exported = false.

For example, to skip repository export:

 @RepositoryRestResource(exported = false) interface PersonRepository extends CrudRepository<Person, Long> {} 
-1
source

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


All Articles