如何验证Pageable的大小?

时间:2017-11-24 07:25:42

标签: spring spring-mvc pagination

我正在@RestController使用org.springframework.data.domain.Pageable

如何验证或限制页面大小?

未经任何验证,当客户使用size 10000拨打电话时。实际pageSize2000

这可能导致最后一页的错误信号,我想。

如何验证并通知客户?跟400说说什么?

3 个答案:

答案 0 :(得分:0)

尝试使用自定义批注来验证Pageable对象。如果它不起作用,请尝试参数解析器,如下所示。

您可以在Spring配置中创建扩展WebMvcConfigurerAdapter的参数解析器

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver() {

        @Override
        public Pageable resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer,
                NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
            Pageable p = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
            if (webRequest.getParameter("per_page") != null) {
                int pageSize = Integer.parseInt(webRequest.getParameter("per_page"));
                if (pageSize < 1 || pageSize > 2000) {
                    message = "Invalid page size";
                }
            }
            if (message != null) {
                Set<CustomConstraintViolation> constraintViolations = new HashSet<>();
                constraintViolations.add(new CustomConstraintViolationImpl(message));
                throw new ConstraintViolationException(constraintViolations);
            }
            return new PageRequest(p.getPageNumber(), p.getPageSize());
        }
    };
    resolver.setMaxPageSize(2000);
    argumentResolvers.add(resolver);
    super.addArgumentResolvers(argumentResolvers);
}

此解析程序将确保每个控制器请求的最大页面大小为2000。

当大小超过2000时,您需要抛出ConstraintViolationException。为此,您需要创建自定义ConstraintViolation接口并实现它

public CustomConstraintViolation implements ConstraintViolation<CustomConstraintViolation> {}

public CustomConstraintViolationImpl implements CustomConstraintViolation {

...

}

答案 1 :(得分:0)

您可以编写自定义批注以验证Pageable对象

@Constraint(validatedBy = PageableValidator.class)
@Target( { ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface PageableConstraint {
    String message() default "Invalid pagination";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    int maxPerPage() default 100;;
}

及其实现

public class PageableValidator implements
        ConstraintValidator<PageableConstraint, Pageable> {

    private int maxPerPage;

    @Override
    public void initialize(PageableConstraint constraintAnnotation) {
        maxPerPage=constraintAnnotation.maxPerPage();
    }

    @Override
    public boolean isValid(Pageable value, ConstraintValidatorContext context) {
        return value.getPageSize()<=maxPerPage;
    }
}

,您可以像其他任何Javax验证批注一样在控制器上使用它。

@RestController
@RequestMapping("/api")
@Validated
public class EmployeeRestController {

    @Autowired
    private EmployeeService employeeService;

    @GetMapping("/employees")
    public List<Employee> getAllEmployees(@PageableConstraint(message = "Invalid page size",maxPerPage = 400) Pageable pageable) {
        return employeeService.getAllEmployees();
    }
}

答案 2 :(得分:0)

您可以简单地使用配置

spring.data.web.pageable.max-page-size=400

如果尝试获取401条记录,这不会导致任何错误。仅返回400。 可以通过spring属性配置的更多内容可以在这里找到:

https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html