Home > Mobile >  How does Spring (Boot) work with Pageable in controllers method argument?
How does Spring (Boot) work with Pageable in controllers method argument?

Time:09-30

I'm curious to know how does Spring Boot work with Pageable in controllers methods? I add a Pageable parameter to my controller method and Spring handle it for me.

There is an example:

@GetMapping("search")
public ResponseEntity<List<ProductDTO>> searchProducts(
        @RequestParam(value = "query", required = false, defaultValue = "") String query,
        Pageable pageable) {
    Specification<Product> spec = Specification.where(null); 
    if(!StringUtils.isBlank(query)) {
        Node rootNode = new RSQLParser().parse(query);
        spec = rootNode.accept(new CustomRsqlVisitor<Product>());
    }
    Page<ProductDTO> page = service.searchProducts(spec, pageable);
    // My Additional code....
}

Now let's back to the main question: How does Spring handle Pageable? Then, how can I create the same business for myself to handle Specifications on input methods?

P.S. 1: I used rsql-parser to implement search over my products.

P.S. 2: You can find custom classes that are used to generate Specification under rsql package

CodePudding user response:

You can look at PageableHandlerMethodArgumentResolver#resolveArgument which calls PageableHandlerMethodArgumentResolverSupport#getPageable

https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java

https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.java

CodePudding user response:

You can do this by implementing a custom HandlerMethodArgumentResolver.

Creating a HandlerMethodArgumentResolver:

@Component
public class CustomClassMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(CustomClass.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
            NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        // You can get the values you need from the request and convert it to a new object.
        // Example: String requestPathInfo = nativeWebRequest.getRequest().getPathInfo();
        // Example: String headerUrl = nativeWebRequest.getHeader("X-Url");
        return new CustomClass(/*...*/);
    }
}

Register the HandlerMethodArgumentResolver:

You can have to make our CustomClassMethodArgumentResolver known to Spring Boot.

@Configuration
public class WebConfig implements WebMvcConfigurer {

    //...

    @Override
    public void addArgumentResolvers(
      List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new CustomClassMethodArgumentResolver());
    }
}
  • Related