使用Spring REST控制器中的Pageable防止多个排序参数

时间:2018-04-25 11:44:41

标签: java spring sorting spring-data spring-restcontroller

我正在使用Spring Boot和Spring Data repos(虽然不是Spring Data REST)使用API​​。

@GetMapping
public List<Foo> listFoos(
    @SortDefault(value = "name", direction = Sort.Direction.ASC)
    Pageable pageable,
    HttpServletRequest request) {
  FooRepo.findAll(pageable);
}

以上工作正常。我可以通过传递sort参数来排序,但是我对性能影响有点担心。

出于性能原因,我想将其限制为仅支持按单个参数排序。默认情况下,我可以执行?sort=name,createdAt之类的操作,这会生成namecreatedAt订购的查询。鉴于它是一个公共API,我有点担心一些用户滥用它并尝试按照我们尚未优化的一大堆值进行排序。

其次,有些值对排序没有意义。例如,如果Foo有缩略图网址,则按thumbnail排序是没有意义的。是否有能力将排序值列入白名单或列入黑名单?

1 个答案:

答案 0 :(得分:2)

您可以制作CustomSortHandlerMethodArgumentResolver(实施org.springframework.data.web.SortArgumentResolver 春季实施org.springframework.data.web.SortHandlerMethodArgumentResolver

@Configuration
@EnableWebMvc
public class WebMvcContext extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableArgumentResolverhandler = new PageableHandlerMethodArgumentResolver(
                new CustomSortHandlerMethodArgumentResolver()); 

        argumentResolvers.add(handler);
    } 
}

在自定义实现中,您可以创建白/黑列表并自定义整理处理以方便您,并避免常见错误 - 请参阅弹簧的实现

其中一种方式

public class CustomSortHandlerMethodArgumentResolver extends 
        SortHandlerMethodArgumentResolver{



    @Override
    public Sort resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        Sort sort = super.resolveArgument(parameter, mavContainer, webRequest, binderFactory);

        /*
            additional logic for filtering orders        
         */

        return sort != null && sort.iterator().hasNext() ? new Sort(sort.iterator().next()) : null;
    }
}