【发布时间】:2017-01-26 09:36:46
【问题描述】:
我正在 Spring Data Rest 之上构建 REST API。最初扩展 JpaRepository 的所有存储库。最近决定采用更灵活的方法并使用QueryDslPredicateExecutor<T> 和QuerydslBinderCustomizer<Q>.
存储库中公开的几乎所有findAll 方法都应该解决两种情况
principal 有一个角色
ROLE_ADMIN,则不应对来自Pageable,Sort的部分应用过滤principal 没有角色
ROLE_ADMIN我只会返回那些属于当前用户的实体
完成这项工作就像注释 findAll 方法一样简单,如下所示。
@Query("select e from Entity e where e.field = ?#{principal} or 1=?#{hasRole('ROLE_ADMIN') ? 1 : 0}")
Page<Entity> findAll(Pageable pageable);
现在我希望我们的findAll 类似于下面的内容
Page<Entity> findAll(Predicate predicate, Pageable pageable)
Predicate 正在从请求参数构建(由@QuerydslPredicate 提供)并被传递给RepositoryEntityController,这一切都由spring-data-rest 管理,这很棒。
@ResponseBody
@RequestMapping(value = BASE_MAPPING, method = RequestMethod.GET)
public Resources<?> getCollectionResource(@QuerydslPredicate RootResourceInformation resourceInformation,
DefaultedPageable pageable, Sort sort, PersistentEntityResourceAssembler assembler)
throws ResourceNotFoundException, HttpRequestMethodNotSupportedException {
我想调整那个谓词(我想解决上面的 2 个场景)。 这将与下面类似。
BooleanBuilder builder = new BooleanBuilder(predicateBuildFromHttpRequest);
builder.and(predicateAddressingOurRequirements);
builder.getValue();
@PostFilter 不是一个选项,因为所有 repos 的返回类型都是 Page<Entity>。
我想解决的用例对我来说似乎很常见。话虽如此,我查看了 spring-data 和 spring-data-rest 文档,但找不到与我的问题相关的任何内容。
问题是:我是否在这里遗漏了一些明显的东西并且可以快速获胜?还是我需要自己实施自定义解决方案?任何 cmets 都非常感谢!
【问题讨论】:
-
见这里有关自定义用户指定参数的绑定的一些信息。不确定您是否还可以添加其他参数但可能有用:stackoverflow.com/questions/40384132/…
-
除了上述方法之外,还有一种方法是通过 Servlet 过滤器实际修改传入请求并附加额外的 URL 参数。
-
您将无法在 QuerydslBinderCustomizer 中公开新参数。它仅用于自定义默认绑定器行为,即忽略大小写、自定义比较等...
-
自定义过滤器方法是那时我能看到的唯一方法。我在类似的场景中使用过它,它可以工作,但感觉有点 hacky。
标签: spring-security spring-data spring-data-jpa spring-data-rest