我正在使用Spring 4.0.0.RELEASE,Spring Data Commons 1.7.0.M1,Spring Hateoas 0.8.0.RELEASE
我的资源是一个简单的POJO:
public class UserResource extends ResourceSupport { ... }
我的资源汇编器将User对象转换为UserResource对象:
@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<User>
从我的服务中检索,然后将其转换为PagedResources<UserResource>using PagedResourcesAssembler
.
@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返回的内容而不是我的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>
,特别是因为User是一个POJO,没有资源。
所以问题是:它如何工作?
编辑:
我的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);
}
你似乎已经找到了正确的使用方法,但是我想在这里详细介绍一些细节,以便其他人也可以找到。我PagedResourceAssembler在这个答案中也有类似的细节。
表示模型
Spring HATEOAS附带了多种表示模型的基类,这些基类使创建带有链接的表示变得容易。开箱即用提供三种类型的类:
Resource
-项目资源。有效地包装一些捕获单个项目并通过链接丰富它的DTO或实体。Resources
-集合资源,可以是某物的集合,但通常是Resource实例的集合。PagedResources
-的扩展名Resources
可捕获其他分页信息,例如总页数等。所有这些类均源自ResourceSupport
,这是Link实例的基本容器。
Resource assemblers
A ResourceAssembler
现在是缓解组件,用于将你的域对象或DTO转换为此类资源实例。这里的重要部分是,它将一个源对象变成一个目标对象。
因此,PagedResourcesAssembler
会采用Spring Data Page
实例并将其PagedResources
评估为,Page
并创建必要PageMetadata
的prev
和next
链接来浏览页面,从而将其转换为实例。默认情况下-这可能是这里有趣的部分-它将使用普通的SimplePagedResourceAssembler
(的内部类PRA)将页面的各个元素转换为嵌套Resource实例。
为了允许对此进行自定义,PRA提供了其他toResource(…)
方法,这些方法需要委托ResourceAssembler
来处理各个项目。因此,你最终会得到如下结果:
class UserResource extends ResourceSupport { … }
class UserResourceAssembler extends ResourceAssemblerSupport<User, UserResource> { … }
客户端代码现在看起来像这样:
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);
Outlook
从即将推出的Spring Data Commons 1.7 RC1(和Spring HATEOAS 0.9过渡而来)开始,prev和next链接将作为RFC6540兼容URI模板生成,以暴露在HandlerMethodArgumentResolversfor Pageable
和中配置的分页请求参数Sort。
你可以通过注释config类来简化上面显示的配置,该类@EnableSpringDataWebSupport
将使你摆脱所有显式的bean声明。