如何正确使用 Spring Data 中的 PagedResourcesAssembler? [英] How to correctly use PagedResourcesAssembler from Spring Data?
问题描述
我使用的是 Spring 4.0.0.RELEASE、Spring Data Commons 1.7.0.M1、Spring Hateoas 0.8.0.RELEASE
I'm using Spring 4.0.0.RELEASE, Spring Data Commons 1.7.0.M1, Spring Hateoas 0.8.0.RELEASE
我的资源是一个简单的 POJO:
My resource is a simple POJO:
public class UserResource extends ResourceSupport { ... }
我的资源汇编器将 User 对象转换为 UserResource 对象:
My resource assembler converts User objects to UserResource objects:
@Component
public class UserResourceAssembler extends ResourceAssemblerSupport<User, UserResource> {
public UserResourceAssembler() {
super(UserController.class, UserResource.class);
}
@Override
public UserResource toResource(User entity) {
// map User to UserResource
}
}
在我的 UserController 中,我想从我的服务中检索 Page
,然后使用 PagedResourcesAssembler
将其转换为 PagedResources
,就像这里显示的一样:https://stackoverflow.com/a/16794740/1321564
Inside my UserController I want to retrieve Page<User>
from my service and then convert it to PagedResources<UserResource>
using PagedResourcesAssembler
, like displayed here: https://stackoverflow.com/a/16794740/1321564
@RequestMapping(value="", method=RequestMethod.GET)
PagedResources<UserResource> get(@PageableDefault Pageable p, PagedResourcesAssembler assembler) {
Page<User> u = service.get(p)
return assembler.toResource(u);
}
这不会调用 UserResourceAssembler
并且只返回 User
的内容而不是我的自定义 UserResource
.
This doesn't call UserResourceAssembler
and simply the contents of User
are returned instead of my custom UserResource
.
返回单个资源有效:
@Autowired
UserResourceAssembler assembler;
@RequestMapping(value="{id}", method=RequestMethod.GET)
UserResource getById(@PathVariable ObjectId id) throws NotFoundException {
return assembler.toResource(service.getById(id));
}
PagedResourcesAssembler
需要一些通用参数,但是我不能使用 T toResource(T)
,因为我不想转换我的 Page<User>
到 PagedResources
,特别是因为 User
是一个 POJO 而没有 Resource.
The PagedResourcesAssembler
wants some generic argument, but then I can't use T toResource(T)
, because I don't want to convert my Page<User>
to PagedResources<User>
, especially because User
is a POJO and no Resource.
所以问题是:它是如何工作的?
So the question is: How does it work?
我的 WebMvcConfigurationSupport:
My WebMvcConfigurationSupport:
@Configuration
@ComponentScan
@EnableHypermediaSupport
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(pageableResolver());
argumentResolvers.add(sortResolver());
argumentResolvers.add(pagedResourcesAssemblerArgumentResolver());
}
@Bean
public HateoasPageableHandlerMethodArgumentResolver pageableResolver() {
return new HateoasPageableHandlerMethodArgumentResolver(sortResolver());
}
@Bean
public HateoasSortHandlerMethodArgumentResolver sortResolver() {
return new HateoasSortHandlerMethodArgumentResolver();
}
@Bean
public PagedResourcesAssembler<?> pagedResourcesAssembler() {
return new PagedResourcesAssembler<Object>(pageableResolver(), null);
}
@Bean
public PagedResourcesAssemblerArgumentResolver pagedResourcesAssemblerArgumentResolver() {
return new PagedResourcesAssemblerArgumentResolver(pageableResolver(), null);
}
/* ... */
}
解决方案:
@Autowired
UserResourceAssembler assembler;
@RequestMapping(value="", method=RequestMethod.GET)
PagedResources<UserResource> get(@PageableDefault Pageable p, PagedResourcesAssembler pagedAssembler) {
Page<User> u = service.get(p)
return pagedAssembler.toResource(u, assembler);
}
推荐答案
您似乎已经找到了正确的使用方法,但我想在这里详细介绍一些细节,供其他人找到作为好.我在 this answer 中详细介绍了关于 PagedResourceAssembler
.
You seem to have already found out about the proper way to use but I'd like to go into some of the details here a bit for others to find as well. I went into similar detail about PagedResourceAssembler
in this answer.
Spring HATEOAS 为表示模型提供了各种基类,可以轻松创建配备链接的表示.开箱即用提供了三种类型的类:
Spring HATEOAS ships with a variety of base classes for representation models that make it easy to create representations equipped with links. There are three types of classes provided out of the box:
Resource
- 项目资源.有效地环绕一些 DTO 或实体,这些实体捕获单个项目并通过链接对其进行丰富.Resources
- 一个集合资源,可以是一些东西的集合,但通常是一个Resource
实例的集合.PagedResources
-Resources
的扩展,用于捕获额外的分页信息,例如总页数等.
Resource
- an item resource. Effectively to wrap around some DTO or entity that captures a single item and enriches it with links.Resources
- a collection resource, that can be a collection of somethings but usually are a collection ofResource
instances.PagedResources
- an extension ofResources
that captures additional pagination information like the number of total pages etc.
所有这些类都源自 ResourceSupport
,它是 Link
实例的基本容器.
All of these classes derive from ResourceSupport
, which is a basic container for Link
instances.
ResourceAssembler
现在是将域对象或 DTO 转换为此类资源实例的缓解组件.这里的重要部分是,它将一个源对象变成了一个目标对象.
A ResourceAssembler
is now the mitigating component to convert your domain objects or DTOs into such resource instances. The important part here is, that it turns one source object into one target object.
因此 PagedResourcesAssembler
将获取 Spring Data Page
实例并通过评估 Page
将其转换为 PagedResources
实例code> 并创建必要的 PageMetadata
以及 prev
和 next
链接来导航页面.默认情况下 - 这可能是这里有趣的部分 - 它将使用一个普通的 SimplePagedResourceAssembler
(PRA
的内部类)将页面的各个元素转换为嵌套的 SimplePagedResourceAssembler
代码>资源代码>实例.
So the PagedResourcesAssembler
will take a Spring Data Page
instance and transform it into a PagedResources
instance by evaluating the Page
and creating the necessary PageMetadata
as well as the prev
and next
links to navigate the pages. By default - and this is probably the interesting part here - it will use a plain SimplePagedResourceAssembler
(an inner class of PRA
) to transform the individual elements of the page into nested Resource
instances.
为了允许对此进行自定义,PRA
有额外的 toResource(…)
方法,这些方法采用委托 ResourceAssembler
来处理各个项目.所以你最终会得到这样的结果:
To allow to customize this, PRA
has additional toResource(…)
methods that take a delegate ResourceAssembler
to process the individual items. So you end up with something like this:
class UserResource extends ResourceSupport { … }
class UserResourceAssembler extends ResourceAssemblerSupport<User, UserResource> { … }
客户端代码现在看起来像这样:
And the client code now looking something like this:
PagedResourcesAssembler<User> parAssembler = … // obtain via DI
UserResourceAssembler userResourceAssembler = … // obtain via DI
Page<User> users = userRepository.findAll(new PageRequest(0, 10));
// Tell PAR to use the user assembler for individual items.
PagedResources<UserResource> pagedUserResource = parAssembler.toResource(
users, userResourceAssembler);
展望
从即将发布的 Spring Data Commons 1.7 RC1(和 Spring HATEOAS 0.9 传递)开始,prev
和 next
链接将生成为 RFC6540 兼容 URI 模板,用于公开 HandlerMethodArgumentResolvers
中配置的分页请求参数,用于Pageable
和 Sort
.
Outlook
As of the upcoming Spring Data Commons 1.7 RC1 (and Spring HATEOAS 0.9 transitively) the prev
and next
links will be generated as RFC6540 compliant URI templates to expose the pagination request parameters configured in the HandlerMethodArgumentResolvers
for Pageable
and Sort
.
上面显示的配置可以通过使用 @EnableSpringDataWebSupport
注释配置类来简化,这将使您摆脱所有显式的 bean 声明.
The configuration you've shown above can be simplified by annotating the config class with @EnableSpringDataWebSupport
which would let you get rid off all the explicit bean declarations.
这篇关于如何正确使用 Spring Data 中的 PagedResourcesAssembler?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!