我正在使用最新的 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
亲切的问候,
斯蒂芬·艾伯特