2016-05-13 7 views
0

In einem Frühlings-Web RestController wir verwenden PagedResources ResponseEntities zu erstellen. Wir haben eine RequestMethod, die eine Hintergrundsuche für Elemente in einem Umkreis von 5km auslöst, wenn es in 10km, 20km, kein Ergebnis gibt, bis wir irgendein Element finden.Wie Extend PagedResourceAssembler

Da wir jetzt die gegebenen Optionen vom Client ändern (die Ressource wird mit einer gegebenen Entfernung aufgerufen), wollen wir dem Client den geänderten Suchabstand zurückgeben. Die eigentliche Antwort wird dann so etwas wie diese:

{ 
    "_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 
    } 
} 

Nun ist die Frage:

  • Wie kann ich verlängern PagedResourcesAssembler, so dass es keine zusätzliche Seite Informationen zurück?

Ich dachte, es wäre genug, ein erweiterte Page zu schaffen, wird hinzufügen, so PagedResourcesAssembler die zusätzliche Informationen zu den Seiteninformationen, aber dies war nicht der Fall.

ResponseEntity.ok(pagedResourcesAssembler.toResource(page, resourceAssembler));

Ich habe dann versucht die PagedResourcesAssembler selbst außer Kraft zu setzen, aber da es viele private Methoden verwendet das Aufschalten von PagedResourcesAssembler.createResource ist nützlich, nicht wirklich.

Ich denke, ich vermisse etwas komplett. Kann mir bitte jemand erklären, wie ich in meiner Response zusätzliche Informationen hinzufügen kann? Ich bin mir sicher, dass es einen viel einfacheren Weg dafür gibt.

Da ich eine Information hinzugefügt werden soll, das die ganze Liste betrifft, ich möchte nicht, diese Informationen in einer einzigen Ressource einfügen nur für die Bequemlichkeit.

Antwort

0

der Tat ein Weg zu gehen ist Ihre eigene Seite Ressource erstellen und Ihr Unternehmen anpassen, wie gewünscht. Dies umfasst den zu rendernden Inhalt und die Metadaten wie Suchentfernung, Größe und so weiter. Hier

ist ein exemple:

/** 
* 
* 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; 
    } 
} 

Können Sie unten eine komplette example von finden können, wie benutzerdefinierte ausgelagerten Ressourcen zu nutzen.

0

Danke für das Beispiel Hassam, aber ich war mehr oder weniger an die vorhandene Antwortstruktur durch hateoas bereitgestellt gebunden!

Ich löste das Problem tatsächlich durch einen Wrapper in den RestController zu schaffen, die eine neue Antwort erstellt und fügt die benötigten Informationen rund um die von PagedResourcesAssembler erstellt Antwort.