diff --git a/pom.xml b/pom.xml
index 6ebe5c9eab..653adc2479 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-commons
- 2.0.0.BUILD-SNAPSHOT
+ 2.0.0.DATACMNS-822-SNAPSHOT
Spring Data Core
diff --git a/src/main/asciidoc/repositories.adoc b/src/main/asciidoc/repositories.adoc
index 75ec691195..edf10b3eba 100644
--- a/src/main/asciidoc/repositories.adoc
+++ b/src/main/asciidoc/repositories.adoc
@@ -923,7 +923,16 @@ This method signature will cause Spring MVC try to derive a Pageable instance fr
|`sort`|Properties that should be sorted by in the format `property,property(,ASC\|DESC)`. Default sort direction is ascending. Use multiple `sort` parameters if you want to switch directions, e.g. `?sort=firstname&sort=lastname,asc`.
|===============
-To customize this behavior extend either `SpringDataWebConfiguration` or the HATEOAS-enabled equivalent and override the `pageableResolver()` or `sortResolver()` methods and import your customized configuration file instead of using the `@Enable`-annotation.
+To customize this behavior register a bean implementing the interface `PageableHandlerMethodArgumentResolverCustomizer` or `SortHandlerMethodArgumentResolverCustomizer` respectively. It's `customize()` method will get called allowing you to change settings. Like in the following example.
+
+[source, java]
+----
+@Bean SortHandlerMethodArgumentResolverCustomizer sortCustomizer() {
+ return s -> s.setPropertyDelimiter("<-->");
+}
+----
+
+If setting the properties of an existing `MethodArgumentResolver` isn't sufficient for your purpose extend either `SpringDataWebConfiguration` or the HATEOAS-enabled equivalent and override the `pageableResolver()` or `sortResolver()` methods and import your customized configuration file instead of using the `@Enable`-annotation.
In case you need multiple `Pageable` or `Sort` instances to be resolved from the request (for multiple tables, for example) you can use Spring's `@Qualifier` annotation to distinguish one from another. The request parameters then have to be prefixed with `${qualifier}_`. So for a method signature like this:
diff --git a/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java b/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java
index ef9351a308..069f2d6c01 100644
--- a/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java
+++ b/src/main/java/org/springframework/data/web/config/HateoasAwareSpringDataWebConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 the original author or authors.
+ * Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
* @author Oliver Gierke
* @author Nick Williams
* @author Ben Hale
+ * @author Vedran Pavic
*/
@Configuration
public class HateoasAwareSpringDataWebConfiguration extends SpringDataWebConfiguration {
@@ -56,7 +57,11 @@ public HateoasAwareSpringDataWebConfiguration(ApplicationContext context,
@Bean
@Override
public HateoasPageableHandlerMethodArgumentResolver pageableResolver() {
- return new HateoasPageableHandlerMethodArgumentResolver(sortResolver());
+
+ HateoasPageableHandlerMethodArgumentResolver pageableResolver = //
+ new HateoasPageableHandlerMethodArgumentResolver(sortResolver());
+ customizePageableResolver(pageableResolver);
+ return pageableResolver;
}
/*
@@ -66,7 +71,10 @@ public HateoasPageableHandlerMethodArgumentResolver pageableResolver() {
@Bean
@Override
public HateoasSortHandlerMethodArgumentResolver sortResolver() {
- return new HateoasSortHandlerMethodArgumentResolver();
+
+ HateoasSortHandlerMethodArgumentResolver sortResolver = new HateoasSortHandlerMethodArgumentResolver();
+ customizeSortResolver(sortResolver);
+ return sortResolver;
}
@Bean
diff --git a/src/main/java/org/springframework/data/web/config/PageableHandlerMethodArgumentResolverCustomizer.java b/src/main/java/org/springframework/data/web/config/PageableHandlerMethodArgumentResolverCustomizer.java
new file mode 100644
index 0000000000..6b8220e9ce
--- /dev/null
+++ b/src/main/java/org/springframework/data/web/config/PageableHandlerMethodArgumentResolverCustomizer.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.web.config;
+
+import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
+
+/**
+ * Callback interface that can be implemented by beans wishing to customize the
+ * {@link PageableHandlerMethodArgumentResolver} configuration.
+ *
+ * @author Vedran Pavic
+ */
+public interface PageableHandlerMethodArgumentResolverCustomizer {
+
+ /**
+ * Customize the pageable resolver
+ *
+ * @param pageableResolver the {@link PageableHandlerMethodArgumentResolver} to customize
+ */
+ void customize(PageableHandlerMethodArgumentResolver pageableResolver);
+
+}
diff --git a/src/main/java/org/springframework/data/web/config/SortHandlerMethodArgumentResolverCustomizer.java b/src/main/java/org/springframework/data/web/config/SortHandlerMethodArgumentResolverCustomizer.java
new file mode 100644
index 0000000000..67bf79985d
--- /dev/null
+++ b/src/main/java/org/springframework/data/web/config/SortHandlerMethodArgumentResolverCustomizer.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.web.config;
+
+import org.springframework.data.web.SortHandlerMethodArgumentResolver;
+
+/**
+ * Callback interface that can be implemented by beans wishing to customize the
+ * {@link SortHandlerMethodArgumentResolver} configuration.
+ *
+ * @author Vedran Pavic
+ */
+public interface SortHandlerMethodArgumentResolverCustomizer {
+
+ /**
+ * Customize the sort resolver
+ *
+ * @param sortResolver the {@link SortHandlerMethodArgumentResolver} to customize
+ */
+ void customize(SortHandlerMethodArgumentResolver sortResolver);
+
+}
diff --git a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java
index 93e6190dc6..76b4af18e0 100644
--- a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java
+++ b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java
@@ -16,8 +16,10 @@
package org.springframework.data.web.config;
import java.util.List;
+import java.util.Optional;
import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -46,6 +48,7 @@
*
* @since 1.6
* @author Oliver Gierke
+ * @author Vedran Pavic
* @author Jens Schauder
*/
@Configuration
@@ -54,8 +57,13 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
private final ApplicationContext context;
private final ObjectFactory conversionService;
- public SpringDataWebConfiguration(ApplicationContext context,
- @Qualifier("mvcConversionService") ObjectFactory conversionService) {
+ @Autowired private Optional pageableResolverCustomizer;
+ @Autowired private Optional sortResolverCustomizer;
+
+ public SpringDataWebConfiguration( //
+ ApplicationContext context, //
+ @Qualifier("mvcConversionService") ObjectFactory conversionService //
+ ) {
this.context = context;
this.conversionService = conversionService;
@@ -67,7 +75,11 @@ public SpringDataWebConfiguration(ApplicationContext context,
*/
@Bean
public PageableHandlerMethodArgumentResolver pageableResolver() {
- return new PageableHandlerMethodArgumentResolver(sortResolver());
+
+ PageableHandlerMethodArgumentResolver pageableResolver = //
+ new PageableHandlerMethodArgumentResolver(sortResolver());
+ customizePageableResolver(pageableResolver);
+ return pageableResolver;
}
/*
@@ -76,7 +88,10 @@ public PageableHandlerMethodArgumentResolver pageableResolver() {
*/
@Bean
public SortHandlerMethodArgumentResolver sortResolver() {
- return new SortHandlerMethodArgumentResolver();
+
+ SortHandlerMethodArgumentResolver sortResolver = new SortHandlerMethodArgumentResolver();
+ customizeSortResolver(sortResolver);
+ return sortResolver;
}
/*
@@ -95,8 +110,7 @@ public void addFormatters(FormatterRegistry registry) {
FormattingConversionService conversionService = (FormattingConversionService) registry;
- DomainClassConverter converter = new DomainClassConverter<>(
- conversionService);
+ DomainClassConverter converter = new DomainClassConverter<>(conversionService);
converter.setApplicationContext(context);
}
@@ -139,4 +153,13 @@ public void extendMessageConverters(List> converters) {
converters.add(0, new XmlBeamHttpMessageConverter());
}
}
+
+ protected void customizePageableResolver(PageableHandlerMethodArgumentResolver pageableResolver) {
+ pageableResolverCustomizer.ifPresent(c -> c.customize(pageableResolver));
+ }
+
+ protected void customizeSortResolver(SortHandlerMethodArgumentResolver sortResolver) {
+ sortResolverCustomizer.ifPresent(c -> c.customize(sortResolver));
+ }
+
}
diff --git a/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java b/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java
index e78e736cb9..5ebc6382b4 100755
--- a/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java
+++ b/src/test/java/org/springframework/data/web/config/EnableSpringDataWebSupportIntegrationTests.java
@@ -36,6 +36,7 @@
import org.springframework.data.web.SortHandlerMethodArgumentResolver;
import org.springframework.data.web.WebTestUtils;
import org.springframework.data.web.config.EnableSpringDataWebSupport.SpringDataWebConfigurationImportSelector;
+import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.ReflectionUtils;
@@ -49,6 +50,8 @@
* Integration tests for {@link EnableSpringDataWebSupport}.
*
* @author Oliver Gierke
+ * @author Vedran Pavic
+ * @author Jens Schauder
*/
public class EnableSpringDataWebSupportIntegrationTests {
@@ -65,8 +68,31 @@ static class SampleConfig {
}
}
+ @Configuration
+ @EnableWebMvc
+ @EnableSpringDataWebSupport
+ static class PageableResolverCustomizerConfig extends SampleConfig {
+
+ @Bean
+ public PageableHandlerMethodArgumentResolverCustomizer testPageableResolverCustomizer() {
+ return pageableResolver -> pageableResolver.setMaxPageSize(100);
+ }
+ }
+
+ @Configuration
+ @EnableWebMvc
+ @EnableSpringDataWebSupport
+ static class SortResolverCustomizerConfig extends SampleConfig {
+
+ @Bean
+ public SortHandlerMethodArgumentResolverCustomizer testSortResolverCustomizer() {
+ return sortResolver -> sortResolver.setSortParameter("foo");
+ }
+ }
+
@After
public void tearDown() {
+
reEnable(HATEOAS);
reEnable(JACKSON);
}
@@ -165,6 +191,28 @@ public void picksUpWebConfigurationMixins() {
assertThat(names).contains("sampleBean");
}
+ @Test // DATACMNS-822
+ public void picksUpPageableResolverCustomizer() {
+
+ ApplicationContext context = WebTestUtils.createApplicationContext(PageableResolverCustomizerConfig.class);
+ List names = Arrays.asList(context.getBeanDefinitionNames());
+ PageableHandlerMethodArgumentResolver resolver = context.getBean(PageableHandlerMethodArgumentResolver.class);
+
+ assertThat(names).contains("testPageableResolverCustomizer");
+ assertThat((Integer) ReflectionTestUtils.getField(resolver, "maxPageSize")).isEqualTo(100);
+ }
+
+ @Test // DATACMNS-822
+ public void picksUpSortResolverCustomizer() {
+
+ ApplicationContext context = WebTestUtils.createApplicationContext(SortResolverCustomizerConfig.class);
+ List names = Arrays.asList(context.getBeanDefinitionNames());
+ SortHandlerMethodArgumentResolver resolver = context.getBean(SortHandlerMethodArgumentResolver.class);
+
+ assertThat(names).contains("testSortResolverCustomizer");
+ assertThat((String) ReflectionTestUtils.getField(resolver, "sortParameter")).isEqualTo("foo");
+ }
+
private static void assertResolversRegistered(ApplicationContext context, Class>... resolverTypes) {
RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);