2
votes

I'm working on a REST API with Spring Boot (1.4) and also using the PagedResourcesAssembler to create JSON responses with pagination, which works like a charm. The guys from Spring did a great job! However I'm having issues providing the URL query parameters (if provided). I understand that the PagedResourcesAssembler can't figure out URL query parameter on its own, so I wanted to provide a Link for it, using the ControllerLinkBuilder.linkTo(controller, parameters) method:

@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public HttpEntity<PagedResources<Document>> find(final DocumentSearch searchForm, final Pageable pageable, final PagedResourcesAssembler assembler) {

    final Page<Document> documents = documentService.find(searchForm, pageable);

    // this map is just for this example ..
    final Map<String, Object> parameters = new HashMap<>();
    parameters.put("text", "foobar");

    final Link link = ControllerLinkBuilder.linkTo(DocumentController.class, parameters).withSelfRel();

    return ResponseEntity.ok(assembler.toResource(documents, link));
}

as you can see I distinctly provided a parameter for the link, but the corresponding response has no URL query in it:

    {
    "_links": {
        "first": {
            "href": "http://localhost:8080/documents?page=0&size=20"
        },
        "self": {
            "href": "http://localhost:8080/documents"
        },
        "next": {
            "href": "http://localhost:8080/documents?page=1&size=20"
        },
        "last": {
            "href": "http://localhost:8080/documents?page=2&size=20"
        }
    }

I also tried to debug into it, he's calling:

linkTo:123, ControllerLinkBuilder (org.springframework.hateoas.mvc)
expand:152, UriComponents (org.springframework.web.util)
expandInternal:47, HierarchicalUriComponents (org.springframework.web.util)
expandInternal:330, HierarchicalUriComponents (org.springframework.web.util)

expandInternal:340, HierarchicalUriComponents (org.springframework.web.util) until this point he still has my text=foobar, meanwhile as QueryUriTemplateVariable but then at

expandInternal:341, HierarchicalUriComponents (org.springframework.web.util) he isn't going into the for-loop where he would/could put my text=foobar into his result map

any help is very much appreciated.

Best Regards, Peter

UPDATE

In order to make this work, I had to do two things. First, change the method signature and add @RequestParam with the corresponding parameter I'd like to have as parameter in pagination link and second, use the methodOn from ControllerLinkBuilder:

public HttpEntity<PagedResources<Document>> find(@RequestParam(value = "text", required = false) final String text, final Pageable pageable, final PagedResourcesAssembler assembler) {

final Link link = ControllerLinkBuilder.linkTo(
            ControllerLinkBuilder.methodOn(
                    DocumentController.class).find(text, pageable, assembler)).withSelfRel();

Thank you both very much for your help, cheers.

P.s. is there any way to make this work without methodOn?

1
The loop is initiated based on the queryParams map inside HierarchicalUriComponents, not your parameter map. Does that method actually have any parameters declared or is text some random thing you're adding? - rorschach
it was just a random value to see if/how it works, but as zeroflagL suggested, I'll try to provide the query parameter in the request mapping (but sadly not today).. however I'll keep you posted - user3861163

1 Answers

0
votes

Links are generated according to the @RequestMapping. The parameters you pass are only to replace variables in the specified URL. They are not query parameters that are added. You need to do that yourself.