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

前端 未结 6 1749
情书的邮戳
情书的邮戳 2021-01-02 02:56

As the title says, I have a resource object Product extending ResourceSupport. However, the responses I receive have the property \"_links\" instea

相关标签:
6条回答
  • 2021-01-02 03:00

    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.

    0 讨论(0)
  • 2021-01-02 03:08

    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

    0 讨论(0)
  • 2021-01-02 03:11

    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.

    0 讨论(0)
  • 2021-01-02 03:19

    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.

    0 讨论(0)
  • 2021-01-02 03:22

    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> {}
    
    0 讨论(0)
  • 2021-01-02 03:23

    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.

    0 讨论(0)
提交回复
热议问题