Search code examples
springsortingjacksonpageable

Passing Spring pageable in get request


If I send a request from Spring application:

public ResponseEntity<RestResponsePage<Result>> readDocs(
    Pageable pageable
) {
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.add("Authorization", getToken());
    String requestUri = 
      baseAppUrl + "/api/k" + "?page={page}&pageSize={pageSize}&sort={sort}&pageable={pageable}";

    Map<String, Object> urlParameters = new HashMap<>();
    urlParameters.put("page", Integer.toString(pageable.getPageNumber()));
    urlParameters.put("pageSize", Long.toString(pageable.getPageSize()));
    urlParameters.put("sort", pageable.getSort());
    urlParameters.put("pageable", pageable);

    HttpEntity<Void> requestEntity = new HttpEntity<>(requestHeaders);

    ResponseEntity<RestResponsePage<Result>> response = restTemplate.exchange( RestResponsePage
        requestUri,
        HttpMethod.GET,
        requestEntity,
        new ParameterizedTypeReference<RestResponsePage<Result>>() {},
        urlParameters
    );
    return response;
}

to another Spring application:

@GetMapping("/")
@PageableAsQueryParam
public ResponseEntity<Page<Result>> getAll(
        @RequestHeader("Authorization") String token,
        @RequestParam("page") Integer page,
        @RequestParam("pageSize") Integer pageSize,
        @RequestParam("sort") String sort,
        @RequestParam("pageable") Pageable pageable
) {
... 
}

I have got an error saying:

Resolved [org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'org.springframework.data.domain.Pageable'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.domain.Pageable': no matching editors or conversion strategy found]

I know i can pass it seperately by fields like in example above: page, pageSize etc.

But i want also to send Sort that's is inside Pageable object - that's also not correctly deserialized as a Type Sort.

How can I make it so Pageable is correctly deserialized ?

EDIT: regarding answer, I added function like:

UriComponentsBuilder withPageable(UriComponentsBuilder builder,
                                  Pageable pageable) {
    builder.queryParam("page", pageable.getPageNumber()).queryParam("size",
        pageable.getPageSize());
    if (pageable.getSort() != null) {
        StringBuilder sb = new StringBuilder();
        pageable.getSort().forEach(order -> {
            sb.append(order.getProperty()).append(",").append(order.getDirection());
        });
        builder.queryParam("sort", sb.toString());
    }
    return builder;
}

to make sort properly deserialize.


Solution

  • Do not need to use @RequestParam("pageable"). Pageable Abstract interface for pagination information. pageSize, pageNumber, sort already provided on the Pageable

    Sample Controller

    @Controller
    public class Controller {
    
      @GetMapping("/...")
      public List<...> findAll(Pageable pageable) {
        log.debug("pageable: {}", pageable);
        // ...
      }
    
    }
    

    MockRequetBuilders

    RequestBuilder request = MockMvcRequestBuilders.get("/url")
                             .param("page", "1")
                             .param("size", "5")
                             .param("sort", "name,DESC"); // column, ASC|DESC
    
    ResultActions actions = mockMvc.perform(request);
    
    actions.andExpect(...);
    

    RestTemplate

    URI uri = UriComponentsBuilder.fromHttpUrl("/url")
            .queryParam("page", pageable.getPageNumber())
            .queryParam("size", pageable.getPageSize())
            .queryParam("sort", pageable.getSort())
            .build()
            .toUri();
    
    HttpHeaders headers = new HttpHeaders();
    headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
    HttpEntity<?> entity = new HttpEntity<>(headers);
    
    ResponseEntity<...> response = restTemplate.exchange(uri, HttpMethod.GET, entity, ...);
    

    https://reflectoring.io/spring-boot-paging/

    https://cursos.alura.com.br/forum/topico-no-primary-or-single-unique-constructor-found-for-interface-org-springframework-data-domain-pageable-195442