Skip to content

Commit c9fe720

Browse files
committed
Add support for resolving Optional<Pageable>
Fix GH-3155
1 parent f305308 commit c9fe720

File tree

4 files changed

+118
-1
lines changed

4 files changed

+118
-1
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2013-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.web;
17+
18+
import org.springframework.core.MethodParameter;
19+
import org.springframework.data.domain.Pageable;
20+
import org.springframework.lang.Nullable;
21+
import org.springframework.web.bind.support.WebDataBinderFactory;
22+
import org.springframework.web.context.request.NativeWebRequest;
23+
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
24+
import org.springframework.web.method.support.ModelAndViewContainer;
25+
26+
import java.util.Optional;
27+
28+
/**
29+
* Optional wrapper resolver for {@link PageableHandlerMethodArgumentResolver}.
30+
*
31+
* @author Yanming Zhou
32+
*/
33+
public class OptionalPageableHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
34+
35+
private final PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver;
36+
37+
/**
38+
* Constructs an instance of this resolver with the specified {@link PageableHandlerMethodArgumentResolver}.
39+
*
40+
* @param pageableHandlerMethodArgumentResolver the pageable resolver to use
41+
*/
42+
public OptionalPageableHandlerMethodArgumentResolver(PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver) {
43+
this.pageableHandlerMethodArgumentResolver = pageableHandlerMethodArgumentResolver;
44+
}
45+
46+
@Override
47+
public boolean supportsParameter(MethodParameter parameter) {
48+
return Optional.class == parameter.getParameterType() && Pageable.class == parameter.nested().getParameterType();
49+
}
50+
51+
@Override
52+
public Optional<Pageable> resolveArgument(MethodParameter methodParameter, @Nullable ModelAndViewContainer mavContainer,
53+
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) {
54+
return Optional.of(pageableHandlerMethodArgumentResolver.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory));
55+
}
56+
}

src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.data.repository.support.DomainClassConverter;
3030
import org.springframework.data.util.Lazy;
3131
import org.springframework.data.web.OffsetScrollPositionHandlerMethodArgumentResolver;
32+
import org.springframework.data.web.OptionalPageableHandlerMethodArgumentResolver;
3233
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
3334
import org.springframework.data.web.ProjectingJackson2HttpMessageConverter;
3435
import org.springframework.data.web.ProxyingHandlerMethodArgumentResolver;
@@ -96,6 +97,12 @@ public void setBeanClassLoader(ClassLoader classLoader) {
9697
this.beanClassLoader = classLoader;
9798
}
9899

100+
@Bean
101+
public OptionalPageableHandlerMethodArgumentResolver optionalPageableResolver() {
102+
103+
return new OptionalPageableHandlerMethodArgumentResolver(pageableResolver.get());
104+
}
105+
99106
@Bean
100107
public PageableHandlerMethodArgumentResolver pageableResolver() {
101108

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2013-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.web;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.springframework.core.MethodParameter;
20+
import org.springframework.data.domain.Pageable;
21+
import org.springframework.mock.web.MockHttpServletRequest;
22+
import org.springframework.web.context.request.ServletWebRequest;
23+
24+
import java.util.Optional;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
28+
/**
29+
* Unit tests for {@link OptionalPageableHandlerMethodArgumentResolver}.
30+
*
31+
* @author Yanming Zhou
32+
*/
33+
class OptionalPageableHandlerMethodArgumentResolverUnitTests {
34+
35+
@Test
36+
void optionalWrapperOfPageable() throws Exception {
37+
38+
OptionalPageableHandlerMethodArgumentResolver resolver = new OptionalPageableHandlerMethodArgumentResolver(new PageableHandlerMethodArgumentResolver());
39+
40+
MethodParameter methodParameter = new MethodParameter(Sample.class.getMethod("supportedMethod", Optional.class), 0);
41+
var request = new MockHttpServletRequest();
42+
request.addParameter("page", "0");
43+
request.addParameter("size", "23");
44+
45+
Optional<Pageable> pageable = resolver.resolveArgument(methodParameter, null, new ServletWebRequest(request), null);
46+
assertThat(pageable).isPresent().get().extracting(Pageable::getPageSize).isEqualTo(23);
47+
}
48+
49+
interface Sample {
50+
51+
void supportedMethod(Optional<Pageable> pageable);
52+
53+
}
54+
}

src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ void registersBasicBeanDefinitions() {
150150
ApplicationContext context = WebTestUtils.createApplicationContext(SampleConfig.class);
151151
var names = Arrays.asList(context.getBeanDefinitionNames());
152152

153-
assertThat(names).contains("pageableResolver", "sortResolver");
153+
assertThat(names).contains("optionalPageableResolver", "pageableResolver", "sortResolver");
154154

155155
assertResolversRegistered(context, SortHandlerMethodArgumentResolver.class,
156156
PageableHandlerMethodArgumentResolver.class);

0 commit comments

Comments
 (0)