Returned json unexpected, has “links” spelled as “_links” and structure different, in Spring hateoas

試著忘記壹切 提交于 2019-11-30 12:59:08

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

Just add the following config to your application.yml file:

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

if you need the output to be like (based on question):

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

Edited:

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

If you have HAL available it will be selected for you by spring boot (and "_links" is what you get with HAL). You should be able to @EnableHypermediaSupport manually to override the defaults.

Another option would be to disable the whole hypermedia auto-configuration feature (this is how it's done in one of the spring-boot + REST examples here):

@EnableAutoConfiguration(exclude = HypermediaAutoConfiguration.class)

As far as I know, HypermediaAutoConfiguration doesn't really do much except for configuring HAL, so it should be perfectly fine to disable it.

I have notice the problem appears at least when you trying to return an object extends ResourseSupport vs object containing object extends ResourseSupport. You may return even List or Array of object(s) extends ResourseSupport and have the same effect. See the example :

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

have response:

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

When try to wrap as List:

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

getting:

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

Changing structure of an answer is not the right decision, but we can try to think further this way.

I've recently had the opposite issue, expected the HAL form (i.e. _links) but always got links, although using @EnableAutoConfiguration.

The solution to my issue might help here as well. Due to copying&pasting from an example I found, I had two mediatypes in my RestController's @RequestMappingannotation

@RequestMapping(path="/example", produces = {MediaType.APPLICATION_JSON_VALUE, "application/hal+json"})

With @EnableAutoConfiguration Spring HATEOAS registers an ObjectMapper for application/hal+json only and in my application there was another one responsible for MediaType.APPLICATION_JSON_VALUE which won the selection and rendered standard JSON.

So my solution to only set produces="application/hal+json" so that the Spring HATEOAS object mapper is choosen. In your case you should try to keep MediaType.APPLICATION_JSON_VALUE

I am sure you are using Spring data with @RepositoryRestResource annotation

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

If you want to remove default HAL behavior you can add following annotaion param

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

Above configurition Spring Data REST to only expose rest endpoints for resources in the parent project, without having to explicitly annotate every repository in the dependency project.

As per doc

Hiding certain repositories, query methods, or fields You may not want a certain repository, a query method on a repository, or a field of your entity to be exported at all. Examples include hiding fields like password on a User object or similar sensitive data. To tell the exporter to not export these items, annotate them with @RestResource and set exported = false.

For example, to skip exporting a Repository:

@RepositoryRestResource(exported = false)
interface PersonRepository extends CrudRepository<Person, Long> {}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!