首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Spring中有没有数据休息的HATEOAS +分页的简单实现吗?

在Spring中有没有数据休息的HATEOAS +分页的简单实现吗?
EN

Stack Overflow用户
提问于 2020-09-19 06:32:08
回答 1查看 1.1K关注 0票数 1

我已经搜索了几天,关于如何实现一个包含HATEOAS链接的Spring REST API +带有Spring boot和JPA (No spring data rest)的分页,就像这个随机示例:

代码语言:javascript
运行
复制
{
    "_links": {
        "first": {
            "href": "http://localhost:8080/api/albums-list?page=0&size=2&sort=title,desc"
        },
        "prev": {
            "href": "http://localhost:8080/api/albums-list?page=0&size=2&sort=title,desc"
        },
        "self": {
            "href": "http://localhost:8080/api/albums-list?page=1&size=2&sort=title,desc"
        },
        "next": {
            "href": "http://localhost:8080/api/albums-list?page=2&size=2&sort=title,desc"
        },
        "last": {
            "href": "http://localhost:8080/api/albums-list?page=4&size=2&sort=title,desc"
        }
    },
    "page": {
        "size": 2,
        "totalElements": 10,
        "totalPages": 5,
        "number": 1
    },
    "_embedded": {
        "albums": [
            {
                "id": 7,
                "title": "Top Hits Vol 7",
                "description": "Top hits vol 7. description",
                "releaseDate": "10-03-1987",
                "actors": [
                    {
                        "id": 4,
                        "firstName": "Janice",
                        "lastName": "Preston",
                        "_links": {
                            "self": {
                                "href": "http://localhost:8080/api/actors/4"
                            }
                        }
                    }
                ],
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/api/actors/7"
                    }
                }
            },
            {
                "id": 6,
                "title": "Top Hits Vol 6",
                "description": "Top hits vol 6. description",
                "releaseDate": "10-03-1986",
                "actors": [
                    {
                        "id": 3,
                        "firstName": "Laverne",
                        "lastName": "Mann",
                        "_links": {
                            "self": {
                                "href": "http://localhost:8080/api/actors/3"
                            }
                        }
                    }
                ],
                "_links": {
                    "self": {
                        "href": "http://localhost:8080/api/actors/6"
                    }
                }
            }
        ]
    }
}

然而,到目前为止,我发现的解决方案复杂得离谱,或者说样板的数量太多了,例如:https://howtodoinjava.com/spring5/hateoas/pagination-links/页面上的教程没有完整地呈现它,但它要求您创建实体、实体的模型和充满样板的长RepresentationModelAssemblerSupport

我也尝试过这个:https://spring.io/guides/tutorials/rest/,但是嵌套的类(我有一对多/多对一的关系)没有得到HATEOAS的链接:

代码语言:javascript
运行
复制
{
    "id": 3,
    "nome": "Amazonas",
    "uf": "AM",
    "cidades": [
        {
        //no HATEOAS in here
            "id": 10003,
            "nome": null,
            "instituicoes": [],
            "uf": "AM"
        },
        {
            "id": 219,
            "nome": "Alvarães",
            "instituicoes": [],
            "uf": "AM"
        }
    ],
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/v1/estados/estadoes/3"
        },
        "estadoes": {
            "href": "http://localhost:8080/api/v1/estados/estadoes"
        }
    }
}

我是说,有没有更简单的解决方案?幸运的是,对于分页,PagingAndSortingRepository是有用的,但是同时拥有分页+ HATEOAS,这是一场噩梦。

EN

回答 1

Stack Overflow用户

发布于 2020-09-19 15:23:08

RepresentationModelAssembler是必需的。如果不需要额外的字段,则不需要模型类extends EntityModel<T>

我的示例实体类是Inventory

RepresentationModelAssembler。您可以在此处添加更多链接。

代码语言:javascript
运行
复制
@Component
public class InventoryModelAssembler implements RepresentationModelAssembler<Inventory, EntityModel<Inventory>> {

    @Override
    public EntityModel<Inventory> toModel(Inventory inventory) {

        return EntityModel.of(inventory,
                linkTo(methodOn(InventoryController.class).get(inventory.getId()))
                        .withSelfRel());
    }
}

控制器

代码语言:javascript
运行
复制
@RestController
@RequestMapping("/inventories")
@RequiredArgsConstructor
public class InventoryController {

    private final InventoryRepository inventoryRepository;

    private final PagedResourcesAssembler pagedResourcesAssembler;

    private final InventoryModelAssembler inventoryModelAssembler;

    @GetMapping
    public ResponseEntity get(Pageable pageable) {

        Page<Inventory> inventories = inventoryRepository.findAll(pageable);

        return ResponseEntity
                .ok()
                .contentType(MediaTypes.HAL_JSON)
                .body(pagedResourcesAssembler.toModel(inventories, inventoryModelAssembler));
    }
}

HAL JSON响应。可以在我的HTML doc中找到完整的长响应。下载它并使用浏览器打开。

代码语言:javascript
运行
复制
{
  "_embedded" : {
    "inventories" : [ {
      "carrier" : "SG",
      "fltNum" : "001",
      "serviceType" : "PAX",
      "fltDate" : "2020-01-20",
      "fltDow" : 1,
      "createdDate" : "2020-06-11T13:21:44.992Z",
      "lastModifiedDate" : "2020-06-11T13:21:44.992Z",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/inventories/5ee22fe8853b0f45ae5fca27"
        }
      }
    }]
  },
  "_links" : {
    "first" : {
      "href" : "http://localhost:8080/inventories?carrier=SG&fltNum=001&page=0&size=10&sort=fltNum,asc&sort=fltDate,desc"
    },
    "self" : {
      "href" : "http://localhost:8080/inventories?carrier=SG&fltNum=001&page=0&size=10&sort=fltNum,asc&sort=fltDate,desc"
    },
    "next" : {
      "href" : "http://localhost:8080/inventories?carrier=SG&fltNum=001&page=1&size=10&sort=fltNum,asc&sort=fltDate,desc"
    },
    "last" : {
      "href" : "http://localhost:8080/inventories?carrier=SG&fltNum=001&page=1&size=10&sort=fltNum,asc&sort=fltDate,desc"
    }
  },
  "page" : {
    "size" : 10,
    "totalElements" : 20,
    "totalPages" : 2,
    "number" : 0
  }
}

完整的代码在Github中共享。如果我的项目比这个答案更有帮助,请考虑在Github中给它打个星。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63963571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档