在 Spring-Web RestController 中,我们使用PagedResources
来创建ResponseEntities。
我们有一个RequestMethod会触发5公里半径范围内的元素的背景搜索,如果没有结果是10公里,20公里,直到找到任何元素。
由于我们现在从客户端更改给定的选项(使用给定距离调用资源),我们希望将更改后的searchDistance返回给客户端。 那么实际的响应将是这样的:
{
"_links": {
"self": {
"href": "http://...
"templated": true
}
},
"_embedded": {
"parcelShopResourceList": [
{
"_id": "2760183530"
...
},
{
"_id": "2760128505"
...
},
{
"_id": "2760162267"
...
},
{
"_id": "2760196914"
...
},
{
"_id": "2760147255"
...
}
]
},
"page": {
"size": 200,
"totalElements": 5,
"totalPages": 1,
"number": 0
"searchDistance": 10
}
}
现在问题:
PagedResourcesAssembler
,以便它会返回任何其他页面信息? 我认为创建一个扩展的Page
就足够了,所以PagedResourcesAssembler
会将额外的信息添加到页面信息中,但事实并非如此。
ResponseEntity.ok(pagedResourcesAssembler.toResource(page, resourceAssembler));
然后我试图覆盖PagedResourcesAssembler
本身,但由于它使用了很多私有方法,因此覆盖PagedResourcesAssembler.createResource
并不是真的有用。
我想我完全错过了一些东西。可以请任何人向我解释如何在我的回复中添加其他信息?我相信有一个更简单的方法。
由于我想添加一个关于整个List的信息,我不想为了方便而将这些信息插入到单个资源中。
答案 0 :(得分:0)
确实,一种方法是创建自己的页面资源并根据需要自定义您的实体。这包括要呈现的内容和元数据,如搜索距离,大小等。
这是一个例子:
/**
*
* Pagination for a resource content
*
* @param <T> content to render
*/
public class PagedResource<T> {
private List<T> content;
private final Map metadata;
public PagedResource(Page<T> page, String pageParam, String sizeParam, String sortParam, String sortField) {
super();
this.setContent(page.getContent());
this.metadata = new HashMap();
List<Link> links = new ArrayList<Link>();
if (page.hasPrevious()) {
String path = createBuilder().queryParam(pageParam, page.getNumber() - 1).queryParam(sizeParam, page.getSize()).queryParam(sortParam, sortField).build().toUriString();
Link previousPageLink = new Link(path, Link.REL_PREVIOUS);
links.add(previousPageLink);
}
if (page.hasNext()) {
String path = createBuilder().queryParam(pageParam, page.getNumber() + 1).queryParam(sizeParam, page.getSize()).queryParam(sortParam, sortField).build().toUriString();
Link nextPageLink = new Link(path, Link.REL_NEXT);
links.add(nextPageLink);
}
if (!page.isFirst()) {
Link firstPageLink = buildPageLink(pageParam, 0, sizeParam, page.getSize(), sortParam, sortField, Link.REL_FIRST);
links.add(firstPageLink);
}
if (!page.isLast()) {
int lastPage = page.getTotalPages() - 1;
Link lastPageLink = buildPageLink(pageParam, lastPage, sizeParam, page.getSize(), sortParam, sortField, Link.REL_LAST);
links.add(lastPageLink);
}
Link currentPagelink = buildPageLink(pageParam, page.getNumber(), sizeParam, page.getSize(), sortParam, sortField, Link.REL_SELF);
links.add(currentPagelink);
populateMetadata(page, links);
}
private void populateMetadata(Page<T> page, List<Link> links) {
int per_page = page.getSize();
int totalPages = page.getTotalPages();
int numberOfPageElements = page.getNumberOfElements();
metadata.put("numberOfPageElements", numberOfPageElements);
metadata.put("perPage", per_page);
metadata.put("totalPages", totalPages);
metadata.put("links", links);
}
private Link buildPageLink(String pageParam, int page, String sizeParam, int size, String sortParam, String sortAttribute, String rel) {
String path = createBuilder().queryParam(pageParam, page).queryParam(sizeParam, size).queryParam(sortParam, sortAttribute).toUriString();
Link link = new Link(path, rel);
return link;
}
private ServletUriComponentsBuilder createBuilder() {
return ServletUriComponentsBuilder.fromCurrentRequestUri();
}
public List<T> getContent() {
return content;
}
public void setContent(List<T> content) {
this.content = content;
}
public Map getMetadata() {
return metadata;
}
}
您可以在下面找到有关如何使用自定义分页资源的完整example。
答案 1 :(得分:0)
感谢Hassam示例,但我或多或少地受到hateoas提供的现有响应结构的约束!
我实际上通过在RestController中创建一个包装器来解决问题,该包装器创建一个新的Response并在PagedResourcesAssembler创建的响应周围添加所需的信息。