spring - 如何正确使用 Spring Data 中的 PagedResourcesAssembler?

标签 spring spring-mvc pagination spring-data spring-hateoas

我正在使用 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>来 self 的服务,然后将其转换为 PagedResources<UserResource>使用 PagedResourcesAssembler ,如此处显示: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 .

返回单个资源有效:

@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);
}

最佳答案

您似乎已经找到了正确的使用方法,但我想在这里稍微介绍一些细节,以便其他人也能找到。我在 this answer 中详细介绍了关于 PagedResourceAssembler 的类似细节。 .

表示模型

Spring HATEOAS 附带了各种表示模型的基类,可以轻松创建配备链接的表示。提供了三种开箱即用的类:

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

所有这些类都派生自 ResourceSupport,它是 Link 实例的基本容器。

资源组装器

ResourceAssembler 现在是将域对象或 DTO 转换为此类资源实例的缓解码件。这里重要的部分是,它将 one 源对象转换为 one 目标对象。

所以 PagedResourcesAssembler 将采用 Spring Data Page 实例并通过评估 Page 将其转换为 PagedResources 实例code> 并创建必要的 PageMetadata 以及 prevnext 链接来导航页面。默认情况下 - 这可能是这里有趣的部分 - 它将使用普通的 SimplePagedResourceAssembler(PRA 的内部类)将页面的各个元素转换为嵌套的 资源实例。

为了允许对此进行自定义,PRA 具有附加的 toResource(…) 方法,这些方法采用委托(delegate) 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);

展望

从即将发布的 Spring Data Commons 1.7 RC1(和 Spring HATEOAS 0.9 过渡)开始,prevnext 链接将生成为 RFC6540兼容的 URI 模板公开在 HandlerMethodArgumentResolvers 中为 PageableSort 配置的分页请求参数。

您可以通过使用 @EnableSpringDataWebSupport 注释配置类来简化上面显示的配置,这样您就可以摆脱所有显式的 bean 声明。

关于spring - 如何正确使用 Spring Data 中的 PagedResourcesAssembler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21346387/

相关文章:

java - 使用 Spring MVC 的 XML View

performance - 使用 Doctrine 2.1 EXTRA_LAZY 关联加快分页

Spring 框架 - 注入(inject) bean 子集

java - JSP 和服务器端延迟

java - 每次应用程序重新启动时 Spring Integration 都会加载文件

java - Html 多个具有相同名称的输入元素

javascript - 新添加行的数据表分页

javascript - 带有数组数据的jqgrid中的分页问题

spring - 如何初始化SpringContext一次并跨任务共享?

java - 尽管如此,还是不​​能覆盖bean@Primary Spring注释