【问题标题】:How to get a response in HAL-Format with Spring-Hateoas如何使用 Spring-Hateoas 获得 HAL 格式的响应
【发布时间】:2023-03-18 06:45:01
【问题描述】:

基本上我和发布这个question的成员有同样的问题

当我在我的应用程序中请求单个用户时,我会得到 HAL 格式的响应,就像我希望的那样

http://localhost:8080/api/v1/users/25GET

{
"userId": "25",
"firstname": "Beytullah",
"lastname": "Güneyli",
"username": "gueneylb",
"_links": {
"self": {
  "href": "http://localhost:8080/api/v1/users/25"
 },
"roles": [
  {
    "href": "http://localhost:8080/api/v1/roles/33"
  },
  {
    "href": "http://localhost:8080/api/v1/roles/34"
  }
 ]
 }
 }

但是,当我请求所有用户时,我会得到非 HAL 格式的响应,如下所示:

http://localhost:8080/api/v1/usersGET:

[...

{
"userId": "25",
"firstname": "Beytullah",
"lastname": "Güneyli",
"username": "gueneylb",
"links": [
  {
    "rel": "self",
    "href": "http://localhost:8080/api/v1/users/25"
  },
  {
    "rel": "roles",
    "href": "http://localhost:8080/api/v1/roles/33"
  },
  {
    "rel": "roles",
    "href": "http://localhost:8080/api/v1/roles/34"
  }
]
},

...]

这是我的方法:

@RequestMapping(value = "users", method = RequestMethod.GET, produces = MediaTypes.HAL_JSON_VALUE)
public List<UserResource> list() throws MyException, NotFoundException {
    List<User> userList= userRepository.findAll();
    List<UserResource> resources = new ArrayList<UserResource>();
    for (User user : userList) {
        resources.add(getUserResource(user));
    }
    if(userList == null)
        throw new MyException("List is empty");
    else
        return resources;
}

@RequestMapping(value = "users/{id}", method = RequestMethod.GET)
public UserResource get(@PathVariable Long id) throws NotFoundException {

    User findOne = userRepository.findOne(id);
    if (findOne == null){
        log.error("Unexpected error, User with ID " + id + " not found");
        throw new NotFoundException("User with ID " + id + " not found");
    }
    return getUserResource(findOne);
}

private UserResource getUserResource(User user) throws NotFoundException {
    resource.add(linkTo(UserController.class).slash("users").slash(user.getId()).withSelfRel());
    for(Role role : user.getRoles()){
          resource.add(linkTo(RoleController.class).slash("roles").slash(role.getId()).withRel("roles"));
    }
    return resource;

}

您可以看到这两个方法都调用了getUserResource(User user) 方法。

但是当我在我的数据库中获取所有用户时,_links 的格式不是我想要的。我认为这一定与我返回的资源的List 有关。也许正因为如此,它没有 HAL 格式。我也尝试了 Set 而不是 List 但它给了我相同的响应

【问题讨论】:

    标签: java spring-boot spring-hateoas hypermedia


    【解决方案1】:

    您应该在您的 list() 方法中返回 Resources&lt;UserResource&gt;

    return new Resources(resources);
    

    您还可以向资源本身添加一个自链接以指向列表资源。

    此外,我建议使用 RessourceAssembler 创建资源实例 - 请参阅 http://docs.spring.io/spring-hateoas/docs/0.23.0.RELEASE/reference/html/#fundamentals.resource-assembler

    此外,您可以将分页添加到列表资源中。 为此,您需要:

    • 在您的存储库中使用返回Page&lt;User&gt;findAll 方法。
    • 在您的控制器中自动连接 PagedResourcesAssembler&lt;User&gt;
    • 在您的列表方法中返回PagedResources&lt;UserResource&gt;
    • 使用PagedResourcesAssemblerPage 转换为PagedResources

    这将导致如下结果:

        private final PagedResourcesAssembler<User> pagedResourcesAssembler;
    
        @RequestMapping(value = "users", method = RequestMethod.GET)
        public ResponseEntity<PagedResources<UserResource>> list(Pageable pageable) {
            final Page<User> page = repository.findAll(pageable);
            final Link link = ControllerLinkBuilder.linkTo(ControllerLinkBuilder.methodOn(this.getClass()).list(null)).withSelfRel();
    
            PagedResources<UserResource> resources = page.getContent().isEmpty() ?
                    (PagedResources<UserResource>) pagedResourcesAssembler.toEmptyResource(page, ShippingZoneResource.class, link)
                    : pagedResourcesAssembler.toResource(page, resourceAssembler, link);
    
            return ResponseEntity.ok(resources);
        }
    

    【讨论】:

    • 感谢您提供非常详细和有用的回答!我找到了解决这个问题的另一种方法。我将@EnableHypermediaSupport(type = { HypermediaType.HAL })annotation 添加到我的Controller-Class 中并且它起作用了。但我喜欢你的建议并将使用它。现在我来看看你建议的这个寻呼的东西。非常感谢你:)
    • 我提出了相反的问题。如何避免 HAL 响应格式?我在响应头中清楚地看到content-type: application/json;charset=utf-8,但响应的结果是page: {}, _embeded: {}, _links: {}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    相关资源
    最近更新 更多