Spring使用SpEL Principal

时间:2017-08-27 01:34:35

标签: java spring hibernate spring-mvc

我正在尝试在本文档中使用SpEL documentation通过?#{principal.id}

执行查询过滤结果

问题是Spring返回异常

  

org.hibernate.QueryException:并非所有命名参数都已设置:   [1] [从产品p JOIN p.store s中选择p,p.store,p.category   JOIN p.category c WHERE p.store.id =:id AND p.keywords LIKE:keyword   AND p.store.ownerId =?1];嵌套异常是   java.lang.IllegalArgumentException:org.hibernate.QueryException:不是   所有已命名的参数都已设置:[1] [select p,p.store,   p.category from Product p JOIN p.store s JOIN p.category c WHERE   p.store.id =:id AND p.keywords LIKE:keyword AND p.store.ownerId =?1   ]

我已设置以下代码并正在执行。

@Service
public class myPrincipalExtractor implements PrincipalExtractor {

    @Override
    public UserInfo extractPrincipal(Map<String, Object> map) {

        Map<String,Object> principal = null;

        if (map.containsKey("principal")) {
            principal = (Map<String, Object>) map.get("principal");
        }

        UserInfo user = new UserInfo();

        if (principal != null ) {
            if (principal.containsKey("id")) {
                user.setId(Long.parseLong(principal.get("id").toString()));
            }

            if (principal.containsKey("username")) {
                user.setUsername(principal.get("username").toString());
            }

            if (principal.containsKey("email")) {
                user.setEmail(principal.get("email").toString());
            }
        }

        System.out.println("----> " + user.getUsername() + " -> " + user.getId());

        return user;
    }
}

我正在使用此服务器有一个Spring资源服务器,所以使用下面的翻译从授权服务器获取Id。我确认代码正在执行和翻译,但我得到了上面的例外。

@CrossOrigin
public interface StoreRepository extends CrudRepository<Store, Long>
{
    @Query("select p , p.store, p.category from Product p JOIN p.store s " +
            " JOIN p.category c " +
            " WHERE p.store.id = :id AND p.keywords LIKE %:keyword% AND p.store.ownerId = ?#{principal.id} ")
    List<Product> findByKeywordIgnoreCase(@Param("id") Long id , @Param("keyword") String keyword);
}

查询是......

return new SecurityExpressionRoot(authentication) {
            @Override
            public UserInfo getPrincipal() {
                System.out.println("Fetching the principal has user " + authentication.getPrincipal().toString());
                return (UserInfo) authentication.getPrincipal();
            }
        };

更多信息:

我在SecurityExpressionRoot中执行了此代码,所以现在我知道当我放置SpEL并且ID和用户名存在于对象中时,这实际上是被调用的。还尝试将返回的对象强制转换为Principal,同样的问题也发生了。

  

AND p.store.ownerId =?#{principal.id}

{{1}}

1 个答案:

答案 0 :(得分:1)

在网站示例(https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions)中,他们指定您可以使用?#{principal.id},并且在执行上述代码时会真正调用它,但由于某种原因它在@Query绑定上失败。 但是我尝试用另一个示例案例运行它

@Query("select p , p.store, p.category from Product p JOIN p.store s " +
            " JOIN p.category c " +
            " WHERE p.store.id = :id AND p.keywords LIKE %:keyword% AND p.store.ownerId = ?#{#security.principal.id} ")

这很有效。 我在这里找到了另一个例子: https://github.com/spring-projects/spring-data-examples/blob/master/jpa/security/src/main/java/example/springdata/jpa/security/SecureBusinessObjectRepository.java