SpringBoot分页Pageable最大size的自定义配置

  • 起因

在工作中,涉及到导出的功能,由于导出和搜索的结果是相同的,所以导出和搜索是同一接口。但由于搜索的分页是每页10条,而导出却是没有条数限制的,所以引出下面的问题

  • controller方法如下:

    @PostMapping("/orders/search")
    public Page getOrders(@RequestBody @Valid Search search,
                                          @PageableDefault(
                                                  sort = {"modifiedDate", "createdDate"},
                                                  direction = Sort.Direction.DESC
                                          ) Pageable pageable) {
    
        return preOrderService.getOrders(search, pageable);
    }

    通过前端传递的pagesize来设定分页的大小,在使用中发现无论page的size修改为多大,导出最多只能2000条,于是怀疑源码中可能有最大值的限制,于是跟踪源码发现果真如此,源码如下(仅相关代码):

    /**
    * Extracts paging information from web requests and thus allows injecting {@link Pageable} instances into controller
    * methods. Request properties to be parsed can be configured. Default configuration uses request parameters beginning
    * with {@link #DEFAULT_PAGE_PARAMETER}{@link #DEFAULT_QUALIFIER_DELIMITER}.
    * 
    * 从Web请求中提取分页信息,从而允许将Pageable实例注入controller方法
    * 可以配置要解析的请求属性,默认配置使用以DEFAULT_PAGE_PARAMETER,DEFAULT_QUALIFIER_DELIMITER开头的请求参数
    *
    * @since 1.6
    * @author Oliver Gierke
    * @author Nick Williams
    * @author Mark Paluch
    */
    public class PageableHandlerMethodArgumentResolver implements PageableArgumentResolver {
    
        private static final String DEFAULT_PAGE_PARAMETER = "page";
        private static final String DEFAULT_SIZE_PARAMETER = "size";
        private static final String DEFAULT_PREFIX = "";
        private static final String DEFAULT_QUALIFIER_DELIMITER = "_";
        // 默认page size最大2000
        private static final int DEFAULT_MAX_PAGE_SIZE = 2000;
        static final Pageable DEFAULT_PAGE_REQUEST = new PageRequest(0, 20);
    
        private Pageable fallbackPageable = DEFAULT_PAGE_REQUEST;
        private SortArgumentResolver sortResolver;
        private String pageParameterName = DEFAULT_PAGE_PARAMETER;
        private String sizeParameterName = DEFAULT_SIZE_PARAMETER;
        private String prefix = DEFAULT_PREFIX;
        private String qualifierDelimiter = DEFAULT_QUALIFIER_DELIMITER;
        // maxPageSize 最大2000
        private int maxPageSize = DEFAULT_MAX_PAGE_SIZE;
    
        @Override
        public Pageable resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer,
                NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
    
            assertPageableUniqueness(methodParameter);
    
            Pageable defaultOrFallback = getDefaultFromAnnotationOrFallback(methodParameter);
    
            String pageString = webRequest.getParameter(getParameterNameToUse(pageParameterName, methodParameter));
            // sizeParameterName="size",从请求中拿到size值
            String pageSizeString = webRequest.getParameter(getParameterNameToUse(sizeParameterName, methodParameter));
    
            boolean pageAndSizeGiven = StringUtils.hasText(pageString) && StringUtils.hasText(pageSizeString);
    
            if (!pageAndSizeGiven && defaultOrFallback == null) {
                return null;
            }
    
            int page = StringUtils.hasText(pageString) ? parseAndApplyBoundaries(pageString, Integer.MAX_VALUE, true)
                    : defaultOrFallback.getPageNumber();
            int pageSize = StringUtils.hasText(pageSizeString) ? parseAndApplyBoundaries(pageSizeString, maxPageSize, false)
                    : defaultOrFallback.getPageSize();
    
            // Limit lower bound
            pageSize = pageSize < 1 ? defaultOrFallback.getPageSize() : pageSize;
            // Limit upper bound
            // 无论上面怎么处理,pageSize>2000的话,pageSize=2000,否则就是pageSize的值
            pageSize = pageSize > maxPageSize ? maxPageSize : pageSize;
    
            Sort sort = sortResolver.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
    
            // Default if necessary and default configured
            sort = sort == null && defaultOrFallback != null ? defaultOrFallback.getSort() : sort;
    
            return new PageRequest(page, pageSize, sort);
        }
    }
  • 自定义page配置来解决

    自定义size最大为10000

import org.springframework.context.annotation.Configuration;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.util.List;

@Configuration
public class PageConfig extends WebMvcConfigurerAdapter {

    private static final int PMP_MAX_PAGE_SIZE = 10000;

    @Override
    public void addArgumentResolvers(List argumentResolvers) {
        PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();

        resolver.setMaxPageSize(PMP_MAX_PAGE_SIZE);
        argumentResolvers.add(resolver);
        super.addArgumentResolvers(argumentResolvers);
    }
}

你可能感兴趣的:(spring,boot)