例子说明
在例子中,我们将学习如何分页显示用户的评论。
加入spring data
引入jar包
加入spring data在pom中引入
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.10.RELEASE</version>
</dependency>
在Root上下文的配置
@Configuration
@EnableAsync( mode = AdviceMode.PROXY, proxyTargetClass = false, order = Ordered.HIGHEST_PRECEDENCE )
@EnableTransactionManagement( mode = AdviceMode.PROXY, proxyTargetClass = false, order = Ordered.LOWEST_PRECEDENCE )
@EnableJpaRepositories( basePackages = "cn.wei.flowingflying.customer_support.site.repositories",
entityManagerFactoryRef = "entityManagerFactoryBean",
transactionManagerRef = "jpaTransactionManager"
)
@EnableScheduling
@ComponentScan( basePackages = "cn.wei.flowingflying.customer_support.site",
excludeFilters = @ComponentScan.Filter({Controller.class,ControllerAdvice.class,Endpoint.class}))
public class RootContextConfiguration implements AsyncConfigurer, SchedulingConfigurer{
......
}
在DispatchServlet上下文的配置
简单地可以加上@EnableSpringDataWebSupport,在例子中,我们采用通过代码定制化设置的方式。
@Configuration
@EnableWebMvc
@ComponentScan( basePackages = "cn.wei.flowingflying.customer_support.site",
useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(WebController.class))
public class WebServletContextConfiguration extends WebMvcConfigurerAdapter{
private static final Logger log = LogManager.getLogger();
@Inject private ApplicationContext applicationContext;
......
//【1】SortHandlerMethodArgumentResolver,转换请求中的Sort参数
//【2】PageableHandlerMethodArgumentResolver,转换请求中的Pageable参数
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
//【1.1】设置缺省的排序方式:根据id的升序
Sort defaultSort = new Sort(new Sort.Order(Sort.Direction.ASC, "id"));
//【2.1】设置缺省的分页情况,第一个参数是zero-based page index,如果显示第一页就填0,每页10个条目,采用缺省的排序方式(根据id的升序)
Pageable defaultPageable = new PageRequest(0, 10, defaultSort);
//【1.2】设置Sort的转换器:自动转换请求参数或者@SortDefault标记
SortHandlerMethodArgumentResolver sortResolver = new SortHandlerMethodArgumentResolver();
sortResolver.setSortParameter("paging.sort"); //请求中的排序参数为paging.sort,请对照后面的jsp代码
sortResolver.setFallbackSort(defaultSort);
//【2.2】设置Page的转换器:从web请求中获取也信息,并注入到控制器方法中的Pageable对象中
PageableHandlerMethodArgumentResolver pageableResolver = new PageableHandlerMethodArgumentResolver(sortResolver);
pageableResolver.setMaxPageSize(100);
pageableResolver.setOneIndexedParameters(true); //页的序号从1开始,缺省是false
pageableResolver.setPrefix("paging.");
pageableResolver.setFallbackPageable(defaultPageable);
//【1.3】添加解析器
resolvers.add(sortResolver);
//【2.3】添加解析器
resolvers.add(pageableResolver);
}
//org.springframework.data.repository.support.DomainClassConverter:将请求参数和路径进行转换
@Override
public void addFormatters(FormatterRegistry registry) {
if(!(registry instanceof FormattingConversionService)){
log.warn("Unable to register Spring Data JPA converter.");
return;
}
// DomainClassConverter adds itself to the registry。
// org.springframework.core.convert.converter.Converter to convert arbitrary input into domain classes managed by Spring Data CrudRepositorys. The implementation uses a ConversionService in turn to convert the source type into the domain class' id type which is then converted into a domain class object by using a CrudRepository. 也就是根据id自动获得一个entity
DomainClassConverter<FormattingConversionService> converter =
new DomainClassConverter<>((FormattingConversionService)registry);
converter.setApplicationContext(this.applicationContext);
}
......
}
如果有多个dispatchServlet,如果需要使用到分页和排序,我们也进行相应的的设置,相关的缺省参数不一样,代码例子如下:
@Configuration @EnableWebMvc @ComponentScan( basePackages = "cn.wei.flowingflying.customer_support.site", useDefaultFilters = false, includeFilters = @ComponentScan.Filter({RestEndpoint.class, RestEndpointAdvice.class}) ) public class RestServletContextConfiguration extends WebMvcConfigurerAdapter{ private static final Logger log = LogManager.getLogger(); @Inject ApplicationContext applicationContext; ...... @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { Sort defaultSort = new Sort(new Sort.Order(Sort.Direction.ASC, "id")); Pageable defaultPageable = new PageRequest(0, 20, defaultSort); SortHandlerMethodArgumentResolver sortResolver = new SortHandlerMethodArgumentResolver(); sortResolver.setSortParameter("$paging.sort"); sortResolver.setFallbackSort(defaultSort); PageableHandlerMethodArgumentResolver pageableResolver = new PageableHandlerMethodArgumentResolver(sortResolver); pageableResolver.setMaxPageSize(200); pageableResolver.setOneIndexedParameters(true); pageableResolver.setPrefix("$paging."); pageableResolver.setFallbackPageable(defaultPageable); resolvers.add(sortResolver); resolvers.add(pageableResolver); } @Override public void addFormatters(FormatterRegistry registry){ if(!(registry instanceof FormattingConversionService)){ log.warn("Unable to register Spring Data JPA converter."); return; } DomainClassConverter<FormattingConversionService> converter = new DomainClassConverter<>((FormattingConversionService)registry); converter.setApplicationContext(this.applicationContext); } }
对于RESTful接口分页的信息除了URL外,例如http://localhost:8080/persons?page=1&size=5&sort,还可以使用HTTP Range headers: Range, Content-Range, If-Range, Accept-Ranges,而相关的返回代码:
- 206 (Partial Content)
- 413 (Request Entity Too Large)
- 416 (Requested Range Not Satisfiable).