DATACMNS-335 - PageableHandlerMethodArgumentResolver now has configurable max page size.
The default is set to 2000.
This commit is contained in:
@@ -47,8 +47,7 @@ public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgum
|
||||
* that if you need to stick to the former request parameters an 1-indexed behavior. This will be removed in the next
|
||||
* major version (1.7). So consider migrating to the new way of exposing request parameters.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PageableHandlerMethodArgumentResolver LEGACY;
|
||||
@Deprecated public static final PageableHandlerMethodArgumentResolver LEGACY;
|
||||
|
||||
static {
|
||||
LEGACY = new PageableHandlerMethodArgumentResolver();
|
||||
@@ -65,6 +64,7 @@ public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgum
|
||||
private static final String DEFAULT_SIZE_PROPERTY = "size";
|
||||
private static final String DEFAULT_PREFIX = "";
|
||||
private static final String DEFAULT_QUALIFIER_SEPARATOR = "_";
|
||||
private static final int DEFAULT_MAX_PAGE_SIZE = 2000;
|
||||
|
||||
private Pageable fallbackPageable = DEFAULT_PAGE_REQUEST;
|
||||
private SortHandlerMethodArgumentResolver sortResolver = new SortHandlerMethodArgumentResolver();
|
||||
@@ -72,6 +72,7 @@ public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgum
|
||||
private String sizeProperty = DEFAULT_SIZE_PROPERTY;
|
||||
private String prefix = DEFAULT_PREFIX;
|
||||
private String qualifierSeparator = DEFAULT_QUALIFIER_SEPARATOR;
|
||||
private int maxPageSize = DEFAULT_MAX_PAGE_SIZE;
|
||||
private boolean oneIndexedParameters = false;
|
||||
|
||||
/**
|
||||
@@ -88,6 +89,16 @@ public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgum
|
||||
this.fallbackPageable = fallbackPageable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the maximum page size to be accepted. This allows to put an upper boundary of the page size to prevent
|
||||
* potential attacks trying to issue an {@link OutOfMemoryError}. Defaults to {@link #DEFAULT_MAX_PAGE_SIZE}.
|
||||
*
|
||||
* @param maxPageSize the maxPageSize to set
|
||||
*/
|
||||
public void setMaxPageSize(int maxPageSize) {
|
||||
this.maxPageSize = maxPageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the parameter name to be used to find the page number in the request. Defaults to {@code page}.
|
||||
*
|
||||
@@ -173,12 +184,12 @@ public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgum
|
||||
Pageable pageable = (Pageable) value;
|
||||
|
||||
String pagePropertyName = getParameterNameToUse(pageProperty, parameter);
|
||||
String propertyToLookup = getParameterNameToUse(sizeProperty, parameter);
|
||||
String sizePropertyName = getParameterNameToUse(sizeProperty, parameter);
|
||||
|
||||
int pageNumber = pageable.getPageNumber();
|
||||
|
||||
builder.queryParam(pagePropertyName, oneIndexedParameters ? pageNumber + 1 : pageNumber);
|
||||
builder.queryParam(propertyToLookup, pageable.getPageSize());
|
||||
builder.queryParam(sizePropertyName, pageable.getPageSize() <= maxPageSize ? pageable.getPageSize() : maxPageSize);
|
||||
|
||||
sortResolver.enhance(builder, parameter, pageable.getSort());
|
||||
}
|
||||
@@ -201,6 +212,7 @@ public class PageableHandlerMethodArgumentResolver implements HandlerMethodArgum
|
||||
: defaultOrFallback.getPageNumber();
|
||||
int pageSize = StringUtils.hasText(pageSizeString) ? Integer.parseInt(pageSizeString) : defaultOrFallback
|
||||
.getPageSize();
|
||||
pageSize = pageSize > maxPageSize ? maxPageSize : pageSize;
|
||||
|
||||
Sort sort = sortResolver.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
|
||||
return new PageRequest(page, pageSize, sort == null ? defaultOrFallback.getSort() : sort);
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@@ -48,8 +49,7 @@ public abstract class PageableDefaultUnitTest {
|
||||
static final PageRequest REFERENCE_WITH_SORT = new PageRequest(PAGE_NUMBER, PAGE_SIZE, SORT);
|
||||
static final PageRequest REFERENCE_WITH_SORT_FIELDS = new PageRequest(PAGE_NUMBER, PAGE_SIZE, new Sort(SORT_FIELDS));
|
||||
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
@Rule public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void supportsPageable() {
|
||||
@@ -124,11 +124,16 @@ public abstract class PageableDefaultUnitTest {
|
||||
resolver.resolveArgument(parameter, null, TestUtils.getWebRequest(), null);
|
||||
}
|
||||
|
||||
private void assertSupportedAndResult(MethodParameter parameter, Pageable pageable) throws Exception {
|
||||
protected void assertSupportedAndResult(MethodParameter parameter, Pageable pageable) throws Exception {
|
||||
assertSupportedAndResult(parameter, pageable, TestUtils.getWebRequest());
|
||||
}
|
||||
|
||||
protected void assertSupportedAndResult(MethodParameter parameter, Pageable pageable, NativeWebRequest request)
|
||||
throws Exception {
|
||||
|
||||
HandlerMethodArgumentResolver resolver = getResolver();
|
||||
assertThat(resolver.supportsParameter(parameter), is(true));
|
||||
assertThat(resolver.resolveArgument(parameter, null, TestUtils.getWebRequest(), null), is((Object) pageable));
|
||||
assertThat(resolver.resolveArgument(parameter, null, request, null), is((Object) pageable));
|
||||
}
|
||||
|
||||
protected void assertUriStringFor(Pageable pageable, String expected) {
|
||||
|
||||
@@ -17,9 +17,13 @@ package org.springframework.data.web;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.web.SortDefault.SortDefaults;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PageableHandlerMethodArgumentResolver}. Pulls in defaulting tests from
|
||||
@@ -39,9 +43,30 @@ public class PageableHandlerMethodArgumentResolverUnitTest extends PageableDefau
|
||||
assertUriStringFor(REFERENCE_WITH_SORT_FIELDS, basicString + "&sort=firstname,lastname,asc");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-335
|
||||
*/
|
||||
@Test
|
||||
public void preventsPageSizeFromExceedingMayValueIfConfigured() throws Exception {
|
||||
|
||||
// Write side
|
||||
assertUriStringFor(new PageRequest(0, 200), "page=0&size=100");
|
||||
|
||||
// Read side
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addParameter("page", "0");
|
||||
request.addParameter("size", "200");
|
||||
|
||||
MethodParameter parameter = new MethodParameter(Sample.class.getMethod("supportedMethod", Pageable.class), 0);
|
||||
|
||||
assertSupportedAndResult(parameter, new PageRequest(0, 100), new ServletWebRequest(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PageableHandlerMethodArgumentResolver getResolver() {
|
||||
return new PageableHandlerMethodArgumentResolver();
|
||||
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
|
||||
resolver.setMaxPageSize(100);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,8 +82,8 @@ public class PageableHandlerMethodArgumentResolverUnitTest extends PageableDefau
|
||||
|
||||
void simpleDefault(@PageableDefault(size = PAGE_SIZE, page = PAGE_NUMBER) Pageable pageable);
|
||||
|
||||
void simpleDefaultWithSort(
|
||||
@PageableDefault(size = PAGE_SIZE, page = PAGE_NUMBER, sort = { "firstname", "lastname" }) Pageable pageable);
|
||||
void simpleDefaultWithSort(@PageableDefault(size = PAGE_SIZE, page = PAGE_NUMBER,
|
||||
sort = { "firstname", "lastname" }) Pageable pageable);
|
||||
|
||||
void simpleDefaultWithSortAndDirection(@PageableDefault(size = PAGE_SIZE, page = PAGE_NUMBER, sort = { "firstname",
|
||||
"lastname" }, direction = Direction.DESC) Pageable pageable);
|
||||
|
||||
Reference in New Issue
Block a user