Skip to content

Commit 26b3516

Browse files
committed
DATACMNS-689 - Improved reference documentation on web pagination.
Re-added index and defaulting information to the section that documents the currents state of web pagination. Removed legacy pagination sections as they're not really documenting the very legacy support (that would not even work anymore). Added explicit anchors where missing.
1 parent a61bd14 commit 26b3516

File tree

1 file changed

+5
-143
lines changed

1 file changed

+5
-143
lines changed

src/main/asciidoc/repositories.adoc

+5-143
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ The configuration setup shown above will register a few basic components:
646646
- A `DomainClassConverter` to enable Spring MVC to resolve instances of repository managed domain classes from request parameters or path variables.
647647
- `HandlerMethodArgumentResolver` implementations to let Spring MVC resolve Pageable and Sort instances from request parameters.
648648

649+
[[core.web.basic.domain-class-converter]]
649650
===== DomainClassConverter
650651
The `DomainClassConverter` allows you to use domain types in your Spring MVC controller method signatures directly, so that you don't have to manually lookup the instances via the repository:
651652

@@ -671,6 +672,7 @@ As you can see the method receives a User instance directly and no further looku
671672

672673
NOTE: Currently the repository has to implement `CrudRepository` to be eligible to be discovered for conversion.
673674

675+
[[core.web.basic.paging-and-sorting]]
674676
===== HandlerMethodArgumentResolvers for Pageable and Sort
675677
The configuration snippet above also registers a `PageableHandlerMethodArgumentResolver` as well as an instance of `SortHandlerMethodArgumentResolver`. The registration enables `Pageable` and `Sort` being valid controller method arguments
676678

@@ -699,8 +701,8 @@ This method signature will cause Spring MVC try to derive a Pageable instance fr
699701
.Request parameters evaluated for Pageable instances
700702
[options = "autowidth"]
701703
|===============
702-
|`page`|Page you want to retrieve.
703-
|`size`|Size of the page you want to retrieve.
704+
|`page`|Page you want to retrieve, 0 indexed and defaults to 0.
705+
|`size`|Size of the page you want to retrieve, defaults to 20.
704706
|`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`.
705707
|===============
706708

@@ -879,6 +881,7 @@ public class UserController {
879881

880882
First you declare a repository dependency for each controller to look up the entity managed by the controller or repository respectively. Looking up the entity is boilerplate as well, as it's always a `findOne(…)` call. Fortunately Spring provides means to register custom components that allow conversion between a `String` value to an arbitrary type.
881883

884+
[[web.legacy.property-editors]]
882885
===== PropertyEditors
883886

884887
For Spring versions before 3.0 simple Java `PropertyEditors` had to be used. To integrate with that, Spring Data offers a `DomainClassPropertyEditorRegistrar`, which looks up all Spring Data repositories registered in the `ApplicationContext` and registers a custom `PropertyEditor` for the managed domain class.
@@ -913,144 +916,3 @@ public class UserController {
913916
}
914917
----
915918

916-
ConversionServiceIn Spring 3.0 and later the `PropertyEditor` support is superseded by a new conversion infrastructure that eliminates the drawbacks of `PropertyEditors` and uses a stateless X to Y conversion approach. Spring Data now ships with a `DomainClassConverter` that mimics the behavior of `DomainClassPropertyEditorRegistrar`. To configure, simply declare a bean instance and pipe the `ConversionService` being used into its constructor:
917-
918-
[source, xml]
919-
----
920-
<mvc:annotation-driven conversion-service="conversionService" />
921-
922-
<bean class="org.springframework.data.repository.support.DomainClassConverter">
923-
<constructor-arg ref="conversionService" />
924-
</bean>
925-
----
926-
927-
If you are using JavaConfig, you can simply extend Spring MVC's `WebMvcConfigurationSupport` and hand the `FormatingConversionService` that the configuration superclass provides into the `DomainClassConverter` instance you create.
928-
929-
[source, java]
930-
----
931-
class WebConfiguration extends WebMvcConfigurationSupport {
932-
933-
// Other configuration omitted
934-
935-
@Bean
936-
public DomainClassConverter<?> domainClassConverter() {
937-
return new DomainClassConverter<FormattingConversionService>(mvcConversionService());
938-
}
939-
}
940-
----
941-
942-
[[web-pagination]]
943-
==== Web pagination
944-
945-
When working with pagination in the web layer you usually have to write a lot of boilerplate code yourself to extract the necessary metadata from the request. The less desirable approach shown in the example below requires the method to contain an `HttpServletRequest` parameter that has to be parsed manually. This example also omits appropriate failure handling, which would make the code even more verbose.
946-
947-
[source, java]
948-
----
949-
@Controller
950-
@RequestMapping("/users")
951-
public class UserController {
952-
953-
// DI code omitted
954-
955-
@RequestMapping
956-
public String showUsers(Model model, HttpServletRequest request) {
957-
958-
int page = Integer.parseInt(request.getParameter("page"));
959-
int pageSize = Integer.parseInt(request.getParameter("pageSize"));
960-
961-
Pageable pageable = new PageRequest(page, pageSize);
962-
963-
model.addAttribute("users", userService.getUsers(pageable));
964-
return "users";
965-
}
966-
}
967-
----
968-
969-
The bottom line is that the controller should not have to handle the functionality of extracting pagination information from the request. So Spring Data ships with a `PageableHandlerMethodArgumentResolver` that will do the work for you. The Spring MVC JavaConfig support exposes a `WebMvcConfigurationSupport` helper class to customize the configuration as follows:
970-
971-
[source, java]
972-
----
973-
@Configuration
974-
public class WebConfig extends WebMvcConfigurationSupport {
975-
976-
@Override
977-
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
978-
argumentResolvers.add(new PageableHandlerMethodArgumentResolver());
979-
}
980-
}
981-
----
982-
983-
If you're stuck with XML configuration you can register the resolver as follows:
984-
985-
[source, xml]
986-
----
987-
<bean class="….web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
988-
<property name="customArgumentResolvers">
989-
<list>
990-
<bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver" />
991-
</list>
992-
</property>
993-
</bean>
994-
----
995-
996-
Once you've configured the resolver with Spring MVC it allows you to simplify controllers down to something like this:
997-
998-
[source, java]
999-
----
1000-
@Controller
1001-
@RequestMapping("/users")
1002-
public class UserController {
1003-
1004-
@RequestMapping
1005-
public String showUsers(Model model, Pageable pageable) {
1006-
1007-
model.addAttribute("users", userRepository.findAll(pageable));
1008-
return "users";
1009-
}
1010-
}
1011-
----
1012-
1013-
The `PageableArgumentResolver` automatically resolves request parameters to build a `PageRequest` instance. By default it expects the following structure for the request parameters.
1014-
1015-
.Request parameters evaluated by PageableHandlerMethodArgumentResolver
1016-
[options = "autowidth"]
1017-
|===============
1018-
|`page`|Page you want to retrieve, 0 indexed and defaults to 0.
1019-
|`size`|Size of the page you want to retrieve, defaults to 20.
1020-
|`sort`|A collection of sort directives in the format `($propertyname,)[asc\|desc]?`.
1021-
|===============
1022-
1023-
.Pagination URL parameter examples
1024-
1025-
To retrieve the third page with a maximum page size of 100 with the data sorted by the email property in ascending order use the following url parameter:
1026-
====
1027-
----
1028-
?page=2&size=100&sort=email,asc
1029-
----
1030-
====
1031-
To sort the data by multiple properties in different sort order use the following URL parameter:
1032-
====
1033-
----
1034-
?sort=foo,asc&sort=bar,desc
1035-
----
1036-
====
1037-
1038-
In case you need multiple `Pageable` 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:
1039-
1040-
[source, java]
1041-
----
1042-
public String showUsers(Model model,
1043-
@Qualifier("foo") Pageable first,
1044-
@Qualifier("bar") Pageable second) { … }
1045-
----
1046-
1047-
you have to populate `foo_page` and `bar_page` and the related subproperties.
1048-
1049-
Configuring a global default on bean declaration the `PageableArgumentResolver` will use a `PageRequest` with the first page and a page size of 10 by default. It will use that value if it cannot resolve a `PageRequest` from the request (because of missing parameters, for example). You can configure a global default on the bean declaration directly. If you might need controller method specific defaults for the `Pageable`, annotate the method parameter with `@PageableDefaults` and specify page (through `pageNumber`), page size (through `value`), `sort` (list of properties to sort by), and `sortDir` (the direction to sort by) as annotation attributes:
1050-
1051-
[source, java]
1052-
----
1053-
public String showUsers(Model model,
1054-
@PageableDefaults(pageNumber = 0, value = 30) Pageable pageable) { … }
1055-
----
1056-

0 commit comments

Comments
 (0)