Java Spring数据Rest:返回用户的资源

Java Spring数据Rest:返回用户的资源,java,spring,spring-security,spring-data-rest,Java,Spring,Spring Security,Spring Data Rest,我正在创建一个简单的CRUD应用程序(一个购物清单),其中包含SpringBoot和SpringDataREST。我有一个资源:ShoppingItem。是否有一种简单的方法只返回属于发送请求的用户的资源?(多用户支持)因此用户只能获得自己的ShoppingItem,而不是每个ShoppingItem。 或者我必须自己实现一个控制器,我在哪里这样做 我找到了这种基于用户筛选资源的方法,但这对存储库端点没有帮助 提前感谢出于以下几个原因,您最好实施控制器: 假设您的应用程序具有某种管理界面,可以

我正在创建一个简单的CRUD应用程序(一个购物清单),其中包含SpringBoot和SpringDataREST。我有一个资源:
ShoppingItem
。是否有一种简单的方法只返回属于发送请求的用户的资源?(多用户支持)因此用户只能获得自己的ShoppingItem,而不是每个ShoppingItem。 或者我必须自己实现一个控制器,我在哪里这样做

我找到了这种基于用户筛选资源的方法,但这对存储库端点没有帮助


提前感谢

出于以下几个原因,您最好实施控制器:

  • 假设您的应用程序具有某种管理界面,可以查看所有购物列表(类似于smth的管理员帐户)

  • 或者您需要在一些基于cron的作业中操作购物列表(缺少使用)

  • 代码中的业务规则更适合学习新项目(即,并非所有初级程序员都能轻松应对spring magic)

需要注意的缺点:

  • 您必须模拟spring序列化()的当前行为

    • 出于以下几个原因,您最好实施控制器:

      • 假设您的应用程序具有某种管理界面,可以查看所有购物列表(类似于smth的管理员帐户)

      • 或者您需要在一些基于cron的作业中操作购物列表(缺少使用)

      • 代码中的业务规则更适合学习新项目(即,并非所有初级程序员都能轻松应对spring magic)

      需要注意的缺点:

      • 您必须模拟spring序列化()的当前行为

      如果您使用的是Spring security integration,您可以使用ACL(可能太重)或simple
      postFilter
      如下所示:

      public interface ShoppingItemRepository extends CrudRepository<ShoppingItem, Long> {
          @PostFilter("filterObject.user.getId() == principal.id")
          @Override
          Iterable<ShoppingItem> findAll();   
      }
      
      公共界面ShoppingItemRepository扩展了Crudepository{
      @PostFilter(“filterObject.user.getId()==principal.id”)
      @凌驾
      Iterable findAll();
      }
      
      如果您使用的是Spring security integration,您可以使用ACL(可能太重)或simple
      postFilter
      如下所示:

      public interface ShoppingItemRepository extends CrudRepository<ShoppingItem, Long> {
          @PostFilter("filterObject.user.getId() == principal.id")
          @Override
          Iterable<ShoppingItem> findAll();   
      }
      
      公共界面ShoppingItemRepository扩展了Crudepository{
      @PostFilter(“filterObject.user.getId()==principal.id”)
      @凌驾
      Iterable findAll();
      }
      
      我最近解决了这个问题,请参见

      我发现的最优雅的解决方案是使用AOP,此示例包含QueryDSL和Spring数据REST存储库:

      @Aspect
      @Transactional
      @Component
      public class FilterProjectsAspect {
      
      @Pointcut("execution(*  com.xxx.ProjectRepository.findAll(..))")
          public void projectFindAll() {
          }
      
          @Around("projectFindAll()")
          public Object  filterProjectsByUser(final ProceedingJoinPoint pjp) throws Throwable {
      
              Object[] args = pjp.getArgs();
              for (int i = 0; i < args.length; i++) {
                  if (args[i] instanceof Predicate) {
                      Predicate predicate=(Predicate) args[i];
                      BooleanExpression isProjectOwner =buildExpressionForUser()
                      predicate = ExpressionUtils.allOf(isProjectOwner, predicate);
                      args[i]=predicate;  //Update args
                  }
              return pjp.proceed(args);
          }
      
      }
      
      @方面
      @交易的
      @组成部分
      公共类筛选器项目透视图{
      @切入点(“执行(*com.xxx.ProjectRepository.findAll(..)”)
      公共无效项目findall(){
      }
      @周围(“projectFindAll()”)
      公共对象filterProjectsByUser(最终处理接合点pjp)抛出可丢弃{
      对象[]args=pjp.getArgs();
      对于(int i=0;i
      我最近解决了这个问题,请参见

      我发现的最优雅的解决方案是使用AOP,此示例包含QueryDSL和Spring数据REST存储库:

      @Aspect
      @Transactional
      @Component
      public class FilterProjectsAspect {
      
      @Pointcut("execution(*  com.xxx.ProjectRepository.findAll(..))")
          public void projectFindAll() {
          }
      
          @Around("projectFindAll()")
          public Object  filterProjectsByUser(final ProceedingJoinPoint pjp) throws Throwable {
      
              Object[] args = pjp.getArgs();
              for (int i = 0; i < args.length; i++) {
                  if (args[i] instanceof Predicate) {
                      Predicate predicate=(Predicate) args[i];
                      BooleanExpression isProjectOwner =buildExpressionForUser()
                      predicate = ExpressionUtils.allOf(isProjectOwner, predicate);
                      args[i]=predicate;  //Update args
                  }
              return pjp.proceed(args);
          }
      
      }
      
      @方面
      @交易的
      @组成部分
      公共类筛选器项目透视图{
      @切入点(“执行(*com.xxx.ProjectRepository.findAll(..)”)
      公共无效项目findall(){
      }
      @周围(“projectFindAll()”)
      公共对象filterProjectsByUser(最终处理接合点pjp)抛出可丢弃{
      对象[]args=pjp.getArgs();
      对于(int i=0;i
      您是否使用spring secrity integration来处理您的用户?您是否使用spring secrity integration来处理您的用户?您好,感谢您的建议。类似于post filter的东西是我最初寻找的东西,所以我会接受这一点作为答案,但当我这样做时,不可能将所有shoppinItems作为adm获取在中,是吗?我刚刚在spring文档中读到了postFilter。这正是我想要的。我稍后会尝试,否则如果您使用spring secu>=4,您也可以访问@query中的主体对象。并使用hql(或SQL)编写您自己的请求和筛选用户对于管理员问题。您只需要在postFilter中添加一个规则,让角色管理员不为其角色筛选项目。缺点是筛选器将所有内容提取到内存中,然后过滤对象,这会降低复杂对象的速度。此外,您实际上正在将业务逻辑嵌入注释值字符串中。您是如何操作的你打算维护它吗?这并不能解决cron作业的问题,因为cron作业是在没有用户的情况下运行的。嗨,谢谢你的建议。像post filter这样的东西是我最初想要的,所以我会接受这个作为答案,但是当我这么做的时候,不可能让所有shoppinItems都成为管理员,是吗?我只是重新开始spring文档中关于postFilter的广告。这应该正是我想要的。我稍后会尝试,否则如果您使用spring secu>=4,您也可以访问@query中的主体对象。并使用hql(或SQL)编写您自己的请求和筛选用户对于管理员问题。您只需要在postFilter中添加一个规则,让角色管理员不为其角色筛选项目。缺点是筛选器会将所有内容都提取到内存中,然后再进行筛选