2017-03-17 58 views
2

基本上我都喜欢谁张贴这question如何获得在HAL-格式与Spring-HATEOAS响应

,当我在我的应用程序请求单个用户的成员同样的问题,我得到的HAL响应-format,就像我希望

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,但它给了我相同的回应

回答

1

您应该在list()方法中返回Resources<UserResource>

return new Resources(resources); 

您还可以添加自链接到资源本身指向列表中的资源。

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

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

  • 使用findAll方法在你的仓库返回一个Page<User>
  • 在你的控制器自动装配PagedResourcesAssembler<User>
  • 在列表中方法的返回PagedResources<UserResource>
  • 使用PagedResourcesAssembler转换的PagePagedResources

这将导致这样的事情:

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); 
    } 
+1

谢谢你为你的非常详细和有益的答案!我发现了另一个解决这个问题的方法。我将'@EnableHypermediaSupport(type = {HypermediaType.HAL})'注释添加到我的控制器类中,并且它工作正常。但我喜欢你的建议,并会使用它。现在我将看看你建议的这种分页方式。非常感谢你 :) –