如何使用 Spring-Hateoas 获得 HAL 格式的响应
How to get a response in HAL-Format with Spring-Hateoas
基本上我和发布此帖子的会员有同样的问题question
当我在我的应用程序中请求单个用户时,我得到了 HAL 格式的响应,就像我希望的那样
http://localhost:8080/api/v1/users/25 与 GET:
{
"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/users 与 GET:
[...
{
"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
的格式与我想要的不一样。我认为这一定是关于资源 i return 的 List
。也许正因为如此,它没有 HAL 格式。我也尝试了 Set
而不是 List
但它给了我相同的响应
您应该 return Resources<UserResource>
在您的 list()
方法中。
return new Resources(resources);
您还可以向资源本身添加一个 self-link 以指向列表资源。
此外,我建议使用 RessourceAssembler
创建资源实例 - 请参阅 http://docs.spring.io/spring-hateoas/docs/0.23.0.RELEASE/reference/html/#fundamentals.resource-assembler。
此外,您可以将分页添加到您的列表资源中。
为此,您需要:
- 在您的存储库中使用
findAll
方法,该方法 return 是 Page<User>
。
- 在您的控制器中自动装配
PagedResourcesAssembler<User>
- return
PagedResources<UserResource>
在你的列表方法中
- 使用
PagedResourcesAssembler
将Page
转换为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);
}
基本上我和发布此帖子的会员有同样的问题question
当我在我的应用程序中请求单个用户时,我得到了 HAL 格式的响应,就像我希望的那样
http://localhost:8080/api/v1/users/25 与 GET:
{
"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/users 与 GET:
[...
{
"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
的格式与我想要的不一样。我认为这一定是关于资源 i return 的 List
。也许正因为如此,它没有 HAL 格式。我也尝试了 Set
而不是 List
但它给了我相同的响应
您应该 return Resources<UserResource>
在您的 list()
方法中。
return new Resources(resources);
您还可以向资源本身添加一个 self-link 以指向列表资源。
此外,我建议使用 RessourceAssembler
创建资源实例 - 请参阅 http://docs.spring.io/spring-hateoas/docs/0.23.0.RELEASE/reference/html/#fundamentals.resource-assembler。
此外,您可以将分页添加到您的列表资源中。 为此,您需要:
- 在您的存储库中使用
findAll
方法,该方法 return 是Page<User>
。 - 在您的控制器中自动装配
PagedResourcesAssembler<User>
- return
PagedResources<UserResource>
在你的列表方法中 - 使用
PagedResourcesAssembler
将Page
转换为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);
}