代码之家  ›  专栏  ›  技术社区  ›  Stephane

如何防止对给定列进行排序?

  •  1
  • Stephane  · 技术社区  · 7 年前

    “我的存储库”允许在检索用户列表时对任何列进行排序:

    public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {
    
        @Query("SELECT u FROM User u")
        public Page<User> all(Pageable page);
    
    }
    

    问题是,用户的某些属性无法提供排序,例如 confirmedEmail 财产。

    @Entity
    @Table(name = "user_account")
    @SequenceGenerator(name = "id_generator", sequenceName = "user_account_id_seq", allocationSize = 10)
    public class User extends AbstractEntity {
    
        @Column(nullable = false)
        private String firstname;
        @Column(nullable = false)
        private String lastname;
        @Column(nullable = false, unique = true)
        private EmailAddress email;
        @Column(nullable = false)
        private boolean confirmedEmail;
    
    }
    

    我怎样才能防止这种情况 Pageable 此布尔值上排序的参数 证实 财产?

    Confirmed Angular 数据表。

    此前端事件触发了以下请求:

    SELECT u FROM com.thalasoft.user.data.jpa.domain.User u order by u.confirmed asc
    

    我知道我可以使这个数据表列不可排序,我做到了。但我也希望有一个服务器端的安全。

    更新:我创建了实用程序方法:

      public static final Sort stripColumnsFromSorting(Sort sort, Set<String> nonSortableColumns) {
        return Sort.by(sort.stream().filter(order -> {
          return !nonSortableColumns.contains(order.getProperty());
        }).collect(Collectors.toList()));
      }
    

    Set<String> nonSortableColumns = new HashSet<String>(Arrays.asList("id", "confirmedEmail"));
    
    public ResponseEntity<PagedResources<UserResource>> all(@PageableDefault(sort = { "lastname", "firstname" }, direction = Sort.Direction.ASC) Pageable pageable, Sort sort,
            PagedResourcesAssembler<User> pagedResourcesAssembler, UriComponentsBuilder builder) {
        sort = CommonUtils.stripColumnsFromSorting(sort, nonSortableColumns);
        userService.addSortToPageable(pageable, sort);
    

    但它仍在调用对不可排序列的排序:

    Invoking 'com.thalasoft.user.rest.controller.UserController.all' with arguments [Page request [number: 0, size 5, sort: confirmedEmail: DESC], confirmedEmail: DESC, org.springframework.data.web.MethodParameterAwarePagedResourcesAssembler@78817e7e, org.springframework.web.servlet.support.ServletUriComponentsBuilder@3e49647a]
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Stephane    7 年前

    我认为您可以检查控制器方法的Pageable参数,然后从中删除不必要的字段,如下所示:

    public ResponseEntity<?> myControllerMethod(..., Pageable page) {
    
        Sort newSort = Sort.by(page.getSort()
            .get()
            .filter(order -> !order.getProperty().equals("confirmedEmail"))
            .collect(Collectors.toList()));
    
        PageRequest newPage = PageRequest.of(page.getPageNumber(), page.getPageSize(), newSort);
    
        // using newPage instead of page...          
    }
    

    要指定默认顺序,可以使用 @PageableDefault 注释,例如:

    public ResponseEntity<?> myControllerMethod(..., @PageableDefault(sort = "lastname", direction = ASC) Pageable page) {
        //...
    }