Skip to content

Commit dbc6810

Browse files
committed
DATACMNS-1211 - Add ReactivePageableHandlerMethodArgumentResolver.
Add ReactivePageableHandlerMethodArgumentResolver and extract shared code from imperative PageableHandlerMethodArgumentResolver into PageableHandlerMethodArgumentResolverSupport. Original pull request: #264.
1 parent 48daa4c commit dbc6810

8 files changed

+35
-212
lines changed

src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolver.java

Lines changed: 0 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -67,138 +67,6 @@ public PageableHandlerMethodArgumentResolver(@Nullable SortArgumentResolver sort
6767
this.sortResolver = sortResolver == null ? DEFAULT_SORT_RESOLVER : sortResolver;
6868
}
6969

70-
/**
71-
* Configures the {@link Pageable} to be used as fallback in case no {@link PageableDefault} or
72-
* {@link PageableDefault} (the latter only supported in legacy mode) can be found at the method parameter to be
73-
* resolved.
74-
* <p>
75-
* If you set this to {@literal Optional#empty()}, be aware that you controller methods will get {@literal null}
76-
* handed into them in case no {@link Pageable} data can be found in the request. Note, that doing so will require you
77-
* supply bot the page <em>and</em> the size parameter with the requests as there will be no default for any of the
78-
* parameters available.
79-
*
80-
* @param fallbackPageable the {@link Pageable} to be used as general fallback.
81-
*/
82-
public void setFallbackPageable(Pageable fallbackPageable) {
83-
84-
Assert.notNull(fallbackPageable, "Fallback Pageable must not be null!");
85-
86-
this.fallbackPageable = fallbackPageable;
87-
}
88-
89-
/**
90-
* Returns whether the given {@link Pageable} is the fallback one.
91-
*
92-
* @param pageable can be {@literal null}.
93-
* @since 1.9
94-
* @return
95-
*/
96-
public boolean isFallbackPageable(Pageable pageable) {
97-
return fallbackPageable == null ? false : fallbackPageable.equals(pageable);
98-
}
99-
100-
/**
101-
* Configures the maximum page size to be accepted. This allows to put an upper boundary of the page size to prevent
102-
* potential attacks trying to issue an {@link OutOfMemoryError}. Defaults to {@link #DEFAULT_MAX_PAGE_SIZE}.
103-
*
104-
* @param maxPageSize the maxPageSize to set
105-
*/
106-
public void setMaxPageSize(int maxPageSize) {
107-
this.maxPageSize = maxPageSize;
108-
}
109-
110-
/**
111-
* Retrieves the maximum page size to be accepted. This allows to put an upper boundary of the page size to prevent
112-
* potential attacks trying to issue an {@link OutOfMemoryError}. Defaults to {@link #DEFAULT_MAX_PAGE_SIZE}.
113-
*
114-
* @return the maximum page size allowed.
115-
*/
116-
protected int getMaxPageSize() {
117-
return this.maxPageSize;
118-
}
119-
120-
/**
121-
* Configures the parameter name to be used to find the page number in the request. Defaults to {@code page}.
122-
*
123-
* @param pageParameterName the parameter name to be used, must not be {@literal null} or empty.
124-
*/
125-
public void setPageParameterName(String pageParameterName) {
126-
127-
Assert.hasText(pageParameterName, "Page parameter name must not be null or empty!");
128-
this.pageParameterName = pageParameterName;
129-
}
130-
131-
/**
132-
* Retrieves the parameter name to be used to find the page number in the request. Defaults to {@code page}.
133-
*
134-
* @return the parameter name to be used, never {@literal null} or empty.
135-
*/
136-
protected String getPageParameterName() {
137-
return this.pageParameterName;
138-
}
139-
140-
/**
141-
* Configures the parameter name to be used to find the page size in the request. Defaults to {@code size}.
142-
*
143-
* @param sizeParameterName the parameter name to be used, must not be {@literal null} or empty.
144-
*/
145-
public void setSizeParameterName(String sizeParameterName) {
146-
147-
Assert.hasText(sizeParameterName, "Size parameter name must not be null or empty!");
148-
this.sizeParameterName = sizeParameterName;
149-
}
150-
151-
/**
152-
* Retrieves the parameter name to be used to find the page size in the request. Defaults to {@code size}.
153-
*
154-
* @return the parameter name to be used, never {@literal null} or empty.
155-
*/
156-
protected String getSizeParameterName() {
157-
return this.sizeParameterName;
158-
}
159-
160-
/**
161-
* Configures a general prefix to be prepended to the page number and page size parameters. Useful to namespace the
162-
* property names used in case they are clashing with ones used by your application. By default, no prefix is used.
163-
*
164-
* @param prefix the prefix to be used or {@literal null} to reset to the default.
165-
*/
166-
public void setPrefix(String prefix) {
167-
this.prefix = prefix == null ? DEFAULT_PREFIX : prefix;
168-
}
169-
170-
/**
171-
* The delimiter to be used between the qualifier and the actual page number and size properties. Defaults to
172-
* {@code _}. So a qualifier of {@code foo} will result in a page number parameter of {@code foo_page}.
173-
*
174-
* @param qualifierDelimiter the delimiter to be used or {@literal null} to reset to the default.
175-
*/
176-
public void setQualifierDelimiter(String qualifierDelimiter) {
177-
this.qualifierDelimiter = qualifierDelimiter == null ? DEFAULT_QUALIFIER_DELIMITER : qualifierDelimiter;
178-
}
179-
180-
/**
181-
* Configures whether to expose and assume 1-based page number indexes in the request parameters. Defaults to
182-
* {@literal false}, meaning a page number of 0 in the request equals the first page. If this is set to
183-
* {@literal true}, a page number of 1 in the request will be considered the first page.
184-
*
185-
* @param oneIndexedParameters the oneIndexedParameters to set
186-
*/
187-
public void setOneIndexedParameters(boolean oneIndexedParameters) {
188-
this.oneIndexedParameters = oneIndexedParameters;
189-
}
190-
191-
/**
192-
* Indicates whether to expose and assume 1-based page number indexes in the request parameters. Defaults to
193-
* {@literal false}, meaning a page number of 0 in the request equals the first page. If this is set to
194-
* {@literal true}, a page number of 1 in the request will be considered the first page.
195-
*
196-
* @return whether to assume 1-based page number indexes in the request parameters.
197-
*/
198-
protected boolean isOneIndexedParameters() {
199-
return this.oneIndexedParameters;
200-
}
201-
20270
/*
20371
* (non-Javadoc)
20472
* @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter)
@@ -219,7 +87,6 @@ public Pageable resolveArgument(MethodParameter methodParameter, @Nullable Model
21987
String page = webRequest.getParameter(getParameterNameToUse(getPageParameterName(), methodParameter));
22088
String pageSize = webRequest.getParameter(getParameterNameToUse(getSizeParameterName(), methodParameter));
22189

222-
22390
Sort sort = sortResolver.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
22491
Pageable pageable = getPageable(methodParameter, page, pageSize);
22592

src/main/java/org/springframework/data/web/PageableHandlerMethodArgumentResolverSupport.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -35,7 +35,9 @@
3535
* configured. Default configuration uses request parameters beginning with
3636
* {@link #DEFAULT_PAGE_PARAMETER}{@link #DEFAULT_QUALIFIER_DELIMITER}.
3737
*
38-
* @since 2.1
38+
* @since 2.2
39+
* @see PageableHandlerMethodArgumentResolver
40+
* @see ReactivePageableHandlerMethodArgumentResolver
3941
* @author Mark Paluch
4042
*/
4143
public abstract class PageableHandlerMethodArgumentResolverSupport {
@@ -83,7 +85,7 @@ public void setFallbackPageable(Pageable fallbackPageable) {
8385
* @return
8486
*/
8587
public boolean isFallbackPageable(Pageable pageable) {
86-
return fallbackPageable == null ? false : fallbackPageable.equals(pageable);
88+
return fallbackPageable.equals(pageable);
8789
}
8890

8991
/**

src/main/java/org/springframework/data/web/ReactivePageableHandlerMethodArgumentResolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -32,7 +32,7 @@
3232
* controller methods. Request properties to be parsed can be configured. Default configuration uses request parameters
3333
* beginning with {@link #DEFAULT_PAGE_PARAMETER}{@link #DEFAULT_QUALIFIER_DELIMITER}.
3434
*
35-
* @since 2.1
35+
* @since 2.2
3636
* @author Mark Paluch
3737
*/
3838
public class ReactivePageableHandlerMethodArgumentResolver extends PageableHandlerMethodArgumentResolverSupport

src/main/java/org/springframework/data/web/ReactiveSortHandlerMethodArgumentResolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,7 +31,7 @@
3131
* Reactive {@link HandlerMethodArgumentResolver} to create {@link Sort} instances from query string parameters or
3232
* {@link SortDefault} annotations.
3333
*
34-
* @since 2.1
34+
* @since 2.2
3535
* @author Mark Paluch
3636
*/
3737
public class ReactiveSortHandlerMethodArgumentResolver extends SortHandlerMethodArgumentResolverSupport

src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolver.java

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,12 @@
1515
*/
1616
package org.springframework.data.web;
1717

18-
import java.util.ArrayList;
1918
import java.util.Arrays;
20-
import java.util.List;
2119

2220
import javax.annotation.Nullable;
2321

2422
import org.springframework.core.MethodParameter;
2523
import org.springframework.data.domain.Sort;
26-
import org.springframework.util.Assert;
2724
import org.springframework.util.StringUtils;
2825
import org.springframework.web.bind.support.WebDataBinderFactory;
2926
import org.springframework.web.context.request.NativeWebRequest;
@@ -41,66 +38,8 @@
4138
* @author Mark Paluch
4239
* @author Christoph Strobl
4340
*/
44-
public class SortHandlerMethodArgumentResolver extends SortHandlerMethodArgumentResolverSupport {
45-
46-
private static final String DEFAULT_PARAMETER = "sort";
47-
private static final String DEFAULT_PROPERTY_DELIMITER = ",";
48-
private static final String DEFAULT_QUALIFIER_DELIMITER = "_";
49-
private static final Sort DEFAULT_SORT = Sort.unsorted();
50-
51-
private static final String SORT_DEFAULTS_NAME = SortDefault.SortDefaults.class.getSimpleName();
52-
private static final String SORT_DEFAULT_NAME = SortDefault.class.getSimpleName();
53-
54-
private Sort fallbackSort = DEFAULT_SORT;
55-
private String sortParameter = DEFAULT_PARAMETER;
56-
private String propertyDelimiter = DEFAULT_PROPERTY_DELIMITER;
57-
private String qualifierDelimiter = DEFAULT_QUALIFIER_DELIMITER;
58-
59-
/**
60-
* Configure the request parameter to lookup sort information from. Defaults to {@code sort}.
61-
*
62-
* @param sortParameter must not be {@literal null} or empty.
63-
*/
64-
public void setSortParameter(String sortParameter) {
65-
66-
Assert.hasText(sortParameter, "SortParameter must not be null nor empty!");
67-
this.sortParameter = sortParameter;
68-
}
69-
70-
/**
71-
* Configures the delimiter used to separate property references and the direction to be sorted by. Defaults to
72-
* {@code}, which means sort values look like this: {@code firstname,lastname,asc}.
73-
*
74-
* @param propertyDelimiter must not be {@literal null} or empty.
75-
*/
76-
public void setPropertyDelimiter(String propertyDelimiter) {
77-
78-
Assert.hasText(propertyDelimiter, "Property delimiter must not be null or empty!");
79-
this.propertyDelimiter = propertyDelimiter;
80-
}
81-
82-
/**
83-
* Configures the delimiter used to separate the qualifier from the sort parameter. Defaults to {@code _}, so a
84-
* qualified sort property would look like {@code qualifier_sort}.
85-
*
86-
* @param qualifierDelimiter the qualifier delimiter to be used or {@literal null} to reset to the default.
87-
*/
88-
public void setQualifierDelimiter(String qualifierDelimiter) {
89-
this.qualifierDelimiter = qualifierDelimiter == null ? DEFAULT_QUALIFIER_DELIMITER : qualifierDelimiter;
90-
}
91-
92-
/**
93-
* Configures the {@link Sort} to be used as fallback in case no {@link SortDefault} or {@link SortDefaults} (the
94-
* latter only supported in legacy mode) can be found at the method parameter to be resolved.
95-
* <p>
96-
* If you set this to {@literal null}, be aware that you controller methods will get {@literal null} handed into them
97-
* in case no {@link Sort} data can be found in the request.
98-
*
99-
* @param fallbackSort the {@link Sort} to be used as general fallback.
100-
*/
101-
public void setFallbackSort(Sort fallbackSort) {
102-
this.fallbackSort = fallbackSort;
103-
}
41+
public class SortHandlerMethodArgumentResolver extends SortHandlerMethodArgumentResolverSupport
42+
implements SortArgumentResolver {
10443

10544
/*
10645
* (non-Javadoc)

src/main/java/org/springframework/data/web/SortHandlerMethodArgumentResolverSupport.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,6 +16,7 @@
1616
package org.springframework.data.web;
1717

1818
import java.util.ArrayList;
19+
import java.util.Arrays;
1920
import java.util.Collections;
2021
import java.util.List;
2122
import java.util.Optional;
@@ -35,7 +36,7 @@
3536
* Base class providing methods for handler method argument resolvers to create {@link Sort} instances from request
3637
* parameters or {@link SortDefault} annotations.
3738
*
38-
* @since 2.1
39+
* @since 2.2
3940
* @see SortHandlerMethodArgumentResolver
4041
* @see ReactiveSortHandlerMethodArgumentResolver
4142
* @author Mark Paluch
@@ -203,7 +204,9 @@ Sort parseParameterIntoSort(List<String> source, String delimiter) {
203204
continue;
204205
}
205206

206-
String[] elements = part.split(delimiter);
207+
String[] elements = Arrays.stream(part.split(delimiter)) //
208+
.filter(SortHandlerMethodArgumentResolver::notOnlyDots) //
209+
.toArray(String[]::new);
207210

208211
Optional<Direction> direction = elements.length == 0 ? Optional.empty()
209212
: Direction.fromOptionalString(elements[elements.length - 1]);
@@ -286,6 +289,16 @@ protected List<String> legacyFoldExpressions(Sort sort) {
286289
return builder == null ? Collections.emptyList() : builder.dumpExpressionIfPresentInto(expressions);
287290
}
288291

292+
/**
293+
* Returns whether the given source {@link String} consists of dots only.
294+
*
295+
* @param source must not be {@literal null}.
296+
* @return
297+
*/
298+
static boolean notOnlyDots(String source) {
299+
return StringUtils.hasText(source.replace(".", ""));
300+
}
301+
289302
/**
290303
* Helper to easily build request parameter expressions for {@link Sort} instances.
291304
*

src/test/java/org/springframework/data/web/ReactivePageableHandlerMethodArgumentResolverUnitTests.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -221,22 +221,24 @@ public void detectsFallbackPageableIfNullOneIsConfigured() {
221221
assertThat(resolver.isFallbackPageable(PageRequest.of(0, 10))).isFalse();
222222
}
223223

224-
private ReactivePageableHandlerMethodArgumentResolver getReactiveResolver() {
224+
private static ReactivePageableHandlerMethodArgumentResolver getReactiveResolver() {
225225

226226
ReactivePageableHandlerMethodArgumentResolver resolver = new ReactivePageableHandlerMethodArgumentResolver();
227227
resolver.setMaxPageSize(100);
228228
return resolver;
229229
}
230230

231-
private void assertSupportedAndResult(MethodParameter parameter, Pageable pageable) {
231+
private static void assertSupportedAndResult(MethodParameter parameter, Pageable pageable) {
232232
assertSupportedAndResult(parameter, pageable, TestUtils.getWebfluxRequest());
233233
}
234234

235-
private void assertSupportedAndResult(MethodParameter parameter, Pageable pageable, MockServerHttpRequest request) {
235+
private static void assertSupportedAndResult(MethodParameter parameter, Pageable pageable,
236+
MockServerHttpRequest request) {
236237
assertSupportedAndResult(parameter, pageable, request, getReactiveResolver());
237238
}
238239

239-
private void assertSupportedAndResult(MethodParameter parameter, Pageable pageable, MockServerHttpRequest request,
240+
private static void assertSupportedAndResult(MethodParameter parameter, Pageable pageable,
241+
MockServerHttpRequest request,
240242
SyncHandlerMethodArgumentResolver resolver) {
241243

242244
assertThat(resolver.supportsParameter(parameter)).isTrue();

src/test/java/org/springframework/data/web/ReactiveSortHandlerMethodArgumentResolverUnitTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,

0 commit comments

Comments
 (0)