一尘不染

如何从Spring Data中正确使用PagedResourcesAssembler?

spring

我正在使用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);
}

阅读 701

收藏
2020-04-14

共1个答案

一尘不染

你似乎已经找到了正确的使用方法,但是我想在这里详细介绍一些细节,以便其他人也可以找到。我PagedResourceAssembler在这个答案中也有类似的细节。

表示模型
Spring HATEOAS附带了多种表示模型的基类,这些基类使创建带有链接的表示变得容易。开箱即用提供三种类型的类:

  • Resource-项目资源。有效地包装一些捕获单个项目并通过链接丰富它的DTO或实体。
  • Resources-集合资源,可以是某物的集合,但通常是Resource实例的集合。
  • PagedResources-的扩展名Resources可捕获其他分页信息,例如总页数等。

所有这些类均源自ResourceSupport,这是Link实例的基本容器。

Resource assemblers

A ResourceAssembler现在是缓解组件,用于将你的域对象或DTO转换为此类资源实例。这里的重要部分是,它将一个源对象变成一个目标对象。

因此,PagedResourcesAssembler会采用Spring Data Page实例并将其PagedResources评估为,Page并创建必要PageMetadataprevnext链接来浏览页面,从而将其转换为实例。默认情况下-这可能是这里有趣的部分-它将使用普通的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声明。

2020-04-14