返回json意外,将“链接”拼写为“_links”并且结构不同,在Spring hateoas中

时间:2014-08-21 16:13:54

标签: java spring spring-boot hateoas spring-hateoas

正如标题所说,我有一个扩展Product的资源对象ResourceSupport。但是,我收到的回复具有属性“_links”而不是“links”,并且具有不同的结构。

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

根据HATEOAS Reference,预期为:

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

这是打算的吗?有没有办法改变它,或者如果不是结构那么就是“链接”?

我通过以下代码段添加了selfLink:

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

我正在使用带有以下构建文件的spring boot:

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"
}

5 个答案:

答案 0 :(得分:5)

Spring Boot now(version = 1.3.3.RELEASE)有一个属性来控制PagedResources的输出JSON格式。

只需将以下配置添加到application.yml文件中:

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

如果您需要输出(基于问题):

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

编辑:

顺便说一句,您只需要@EnableSpringDataWebSupport注释即可。

答案 1 :(得分:4)

如果您有HAL可用,它将通过弹簧启动为您选择(并且“_links”是您使用HAL获得的)。您应该能够@EnableHypermediaSupport手动覆盖默认值。

答案 2 :(得分:2)

我注意到问题至少在您尝试返回对象时出现扩展ResourseSupport与对象包含对象扩展了ResourseSupport。 您甚至可以返回List或Array对象扩展ResourseSupport并具有相同的效果。 参见示例:

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

有回应:

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

当尝试换行为List时:

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

得到:

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

更改答案的结构不是正确的决定,但我们可以尝试以这种方式进一步思考。

答案 3 :(得分:0)

我最近遇到了相反的问题,期望使用HAL格式(即_links),尽管使用links却总是得到@EnableAutoConfiguration

我的问题的解决方案在这里也可能有所帮助。由于复制并粘贴了我发现的示例,因此我的RestController的@RequestMapping注释中有两种媒体类型

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

Spring HATEOAS使用@EnableAutoConfiguration仅为application/hal+json注册了一个ObjectMapper,在我的应用程序中,还有一个负责MediaType.APPLICATION_JSON_VALUE的对象赢得了选择并呈现了标准JSON。

因此,我的解决方案仅设置produces="application/hal+json",以便选择Spring HATEOAS对象映射器。在您的情况下,您应尝试保留MediaType.APPLICATION_JSON_VALUE

答案 4 :(得分:-1)

我确信您正在使用带有@RepositoryRestResource注释的Spring数据

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

如果要删除默认的HAL行为,可以添加以下注释参数

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

以上配置Spring Data REST仅公开父项目中资源的休息端点,而不必显式注释依赖项目中的每个存储库。

根据文件

隐藏某些存储库,查询方法或字段 您可能根本不希望导出某个存储库,存储库上的查询方法或实体的字段。示例包括在User对象或类似敏感数据上隐藏密码等字段。要告诉导出器不导出这些项,请使用@RestResource注释它们并设置exported = false。

例如,要跳过导出存储库:

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