0

我正在使用最新的 Spring REST 和 HATEOAS 试图公开指向搜索端点的链接。

这是资源汇编器:

@Component
public class AdminResourceAssembler extends ResourceAssemblerSupport<Admin, AdminResource> {

    public AdminResourceAssembler() {
        super(AdminController.class, AdminResource.class);
    }

    public AdminResource toResource(Admin admin) {
        AdminResource adminResource = createResourceWithId(admin.getId(), admin);
        BeanUtils.copyProperties(admin, adminResource);
        adminResource.add(linkTo(AdminController.class).slash(admin.getId()).slash("module").withRel("module"));        
        return adminResource;
    }

}

这是端点控制器:

@RequestMapping(value = UriMappingConstants.PATH_SEPARATOR + UriMappingConstants.SEARCH, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<PagedResources<AdminResource>> search(@RequestParam(value = "searchTerm", required = true) String searchTerm, @PageableDefault Pageable pageable, PagedResourcesAssembler<Admin> pagedResourcesAssembler, UriComponentsBuilder builder) {
    HttpHeaders responseHeaders = new HttpHeaders();
    Pageable pageRequest = buildPageRequest(pageable.getPageNumber(), pageable.getPageSize());
    Page<Admin> searchedAdmins = adminService.search(searchTerm, pageRequest);
    responseHeaders.setLocation(builder.path(UriMappingConstants.PATH_SEPARATOR + UriMappingConstants.ADMINS + UriMappingConstants.PATH_SEPARATOR + "search").queryParam("searchTerm", searchTerm).queryParam("page", pageable.getPageNumber()).queryParam("size", pageable.getPageSize()).buildAndExpand(searchTerm).toUri());
    PagedResources<AdminResource> adminPagedResources = pagedResourcesAssembler.toResource(searchedAdmins, adminResourceAssembler);
    return new ResponseEntity<PagedResources<AdminResource>>(adminPagedResources, responseHeaders, HttpStatus.OK);
}

private Pageable buildPageRequest(int pageIndex, int pageSize) {
    Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "lastname"), new Sort.Order(Sort.Direction.ASC, "firstname"));
    return new PageRequest(pageIndex, pageSize, sort);
}

首先,我不确定是否应该调用 buildPageRequest 方法并简单地将原始 pageable 传递给搜索服务。

我遇到的问题有两个:

响应中发布的链接缺少 searchTerm 参数:

{"rel":"self","href":"http://localhost:8080/nitro-project-rest/admins/search{?page,size,sort}

我希望它是这样的:

{"rel":"self","href":"http://localhost:8080/nitro-project-rest/admins/search{?searchTerm,page,size,sort}

但同样,作为一个新手,我不确定。

控制器总是获取 10 个项目的第一页,忽略我在请求中提供的页码和大小参数:

curl -H "Accept:application/json" --user joethebouncer:mignet http://localhost:8080/nitro-project-rest/admins/search?searchTerm=irstna&page=3&size=5

我想我离解决方案不远了,但我什至不知道暴露的链接应该是什么样子。

任何方向都会非常好:-)

编辑:添加信息

可分页配置:

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
    argumentResolvers.add(resolver);
    super.addArgumentResolvers(argumentResolvers);
}

该服务只是对存储库的简单包装:

public Page<Admin> search(String searchTerm, Pageable page) {
  return adminRepository.search(searchTerm, page);
}

这是一个接口:

@Query("SELECT a FROM Admin a WHERE LOWER(a.firstname) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.lastname) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.email) LIKE LOWER(CONCAT('%', :searchTerm, '%')) OR LOWER(a.login) LIKE LOWER(CONCAT('%', :searchTerm, '%')) ORDER BY a.lastname ASC, a.firstname ASC") public 

页面搜索(@Param("searchTerm") String searchTerm, Pageable page);

数据库是 JPA 前端的 H2,控制台显示:

可以看到偏移量丢失了...

select admin0_.id as id1_1_, admin0_.version as version2_1_, admin0_.email as email3_1_, admin0_.firstname as firstnam4_1_, admin0_.lastname as lastname5_1_, admin0_.login as login6_1_, admin0_.password as password7_1_, admin0_.password_salt as password8_1_, admin0_.post_login_url as post_log9_1_ from admin admin0_ where lower(admin0_.firstname) like lower(('%'||'irstn'||'%')) order by admin0_.lastname ASC, admin0_.firstname ASC, admin0_.lastname asc, admin0_.firstname asc limit 10

亲切的问候,

斯蒂芬·艾伯特

4

2 回答 2

0

不知道 buildPageRequest 在做什么......但我敢打赌你不需要它,它是你的分页问题的根源

关于自我链接。PagedResourceAssembler 创建了一个非常简单的默认程序...但是您可以构建一个更复杂的程序并将其作为 toResource 方法的第三个参数传入。因此,只需以多种方式中的任何一种方式构建您自己的链接。我建议像:

  linkTo(methodOn(SomeController.class).search(searchTerm, pageable, null, null))

要注意的另一件事是,永远不应该对自我链接进行模板化,因此这是 spring-hateoas 中的一个错误(实际上是一个依赖项),请参阅https://jira.spring.io/browse/DATACMNS-515

于 2014-08-18T21:57:01.917 回答
0

愚蠢的我。我看不到 curl 需要在 url 周围加上双引号来允许多个参数。curl -H "Accept:application/json" --user joethebouncer:mignet "localhost:8080/nitro-project-rest/admins/... 现在可以正常工作了。

于 2014-08-19T09:37:23.433 回答