Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Spring数据REST处理子实体集合中的资源链接_Java_Spring Data Rest_Hateoas_Spring Hateoas - Fatal编程技术网

Java 使用Spring数据REST处理子实体集合中的资源链接

Java 使用Spring数据REST处理子实体集合中的资源链接,java,spring-data-rest,hateoas,spring-hateoas,Java,Spring Data Rest,Hateoas,Spring Hateoas,我正在评估SpringDataREST作为基于AngularJS的应用程序的后端。我很快将我们的领域建模为一组聚合根,并遇到了以下设计障碍: 模型资源 多任务实体 引用多属性资源 我期望属性的HAL_链接放置在每个TaskJSON对象中,但遗憾的是,这些属性仅作为JSON构造根的链接可见 我明白了: { “版本”:0, “名称”:“myModel”, “任务”:[ { “名称”:“任务1” }, { “名称”:“任务2” } ], “_链接”:{ “自我”:{ “href”:”http://

我正在评估SpringDataREST作为基于AngularJS的应用程序的后端。我很快将我们的领域建模为一组聚合根,并遇到了以下设计障碍:

  • 模型资源
  • 多任务实体
  • 引用多属性资源
我期望属性的HAL_链接放置在每个TaskJSON对象中,但遗憾的是,这些属性仅作为JSON构造根的链接可见

我明白了:

{
“版本”:0,
“名称”:“myModel”,
“任务”:[
{
“名称”:“任务1”
},
{
“名称”:“任务2”
}
],
“_链接”:{
“自我”:{
“href”:”http://localhost:8080/models/1"
},
“属性”:{
“href”:”http://localhost:8080/models/1/attributes"
}
}
}
而不是像我想象的那样:

{
“版本”:0,
“名称”:“myModel”,
“任务”:[
{
“名称”:“任务1”,
“_链接”:{
“属性”:{
“href”:”http://localhost:8080/models/1/tasks/1/attributes"
}
}
},
{
“名称”:“任务2”,
“_链接”:{
“属性”:{
“href”:”http://localhost:8080/models/1/tasks/2/attributes"
}
}
],
“_链接”:{
“自我”:{
“href”:”http://localhost:8080/models/1"
},
“属性”:{
“href”:”http://localhost:8080/models/1/attributes"
}
}
}
顺便提一下,在第一个示例中,属性链接以404结尾

我在HAL规范和Spring Data REST文档中都没有看到处理这种情况的任何内容。显然,我可以将任务定义为解决问题的资源,但是我的模型不需要这样做。我觉得这是一个合法的用例

我创建了一个简单的Spring Boot应用程序,它再现了这个问题。模型:

@实体
公共类模型{
@Id@GeneratedValue公共长Id;
@版本公共长版本;
公共字符串名称;
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE})
公开列出任务;
}
@实体
公开课任务{
@Id@GeneratedValue公共长Id;
公共字符串名称;
@许多
公共集合属性;
}
@实体
公共类属性{
@Id@GeneratedValue公共长Id;
@版本公共长版本;
公共字符串名称;
}
和存储库:

@RepositoryRestResource
公共接口模型存储库扩展了分页和排序存储库{
}
@存储资源
公共接口属性存储库扩展了分页和排序存储库{
}

在这里,我可能错过了一些东西,因为这似乎是一个非常简单的用例,但找不到任何有类似问题的人。此外,这可能是我的模型中的一个基本缺陷,如果是这样,我准备听听你的论点:-)

你没有任务存储库-在spring data rest中,如果你没有我认为如果一个任务只包含一个属性,那么你会得到一个链接,但是你有一个集合,所以对属性的访问将是任务资源的一个子资源

因此,您的方案不起作用。我将尝试导出TaskRepository并删除属性repository

然后,模型资源将包含指向其任务的链接,任务资源将嵌入属性


如果您仍然希望将任务内联到您的模型资源中,您可以使用投影。

因为Spring Data REST不以本机方式处理问题中描述的用例,所以第一步是停用任务属性的管理,并确保它们在默认情况下不会序列化ce(exported=false)确保不会为“attributes”rel自动生成(非工作)链接,
@JsonIgnore
确保默认情况下不会呈现属性

@实体
公开课任务{
@身份证
@生成值
公共长id;
公共字符串名称;
@许多
@RestResource(导出=假)
@杰索尼奥雷
公共列表属性;
}
接下来,
\u links
属性仅在资源的根目录下可用,因此我选择实现一个名为“taskAttributes”的新rel,将有多个值,每个任务一个。为了将这些链接添加到资源,我构建了一个自定义
ResourceProcessor
,为了实现实际端点,还构建了一个自定义
ModelController

@组件
公共类ModelResourceProcessor实现ResourceProcessor{
@凌驾
公共资源流程(资源模型资源){
Model Model=modelResource.getContent();
对于(int i=0;i=model.tasks.size()){
返回新的ResponseEntity(未找到HttpStatus.NOT_);
}
列表属性=model.tasks.get(taskIndex.attributes);
列表资源=attributes.stream()
.map(t->assembler.toResource(t))
.collect(toList());
{
  "name": "myModel",
  "tasks": [
    {
      "name": "task1"
    },
    {
      "name": "task2"
    }
  ],
  "_links": {
    "self": {
      "href": "http://localhost:8080/models/1"
    },
    "model": {
      "href": "http://localhost:8080/models/1{?projection}",
      "templated": true
    },
    "taskAttributes": [
      {
        "href": "http://localhost:8080/models/1/task/0/attributes"
      },
      {
        "href": "http://localhost:8080/models/1/task/1/attributes"
      }
    ]
  }
}
{
  "name": "myModel",
  "tasks": [
    {
      "name": "task1",
      "attributes": [
        {
          "name": "attrForTask1",
          "_links": {
            "self": {
              "href": "http://localhost:8080/attributes/1{?projection}",
              "templated": true
            }
          }
        }
      ]
    },
    {
      "name": "task2",
      "attributes": [
        {
          "name": "attrForTask2",
          "_links": {
            "self": {
              "href": "http://localhost:8080/attributes/2{?projection}",
              "templated": true
            }
          }
        },
        {
          "name": "anotherAttrForTask2",
          "_links": {
            "self": {
              "href": "http://localhost:8080/attributes/3{?projection}",
              "templated": true
            }
          }
        },
        ...
      ]
    }
  ],
  "_links": {
    "self": {
      "href": "http://localhost:8080/models/1"
    },
    "model": {
      "href": "http://localhost:8080/models/1{?projection}",
      "templated": true
    }
  }
}