【问题标题】:Jersey and HK2 - Injecting current userJersey 和 HK2 - 注入当前用户
【发布时间】:2015-07-13 08:43:26
【问题描述】:

我正在使用 jersey 2.17 和 HK2 创建一个简单的休息应用程序。 我有一个ContainerRequestFilter 拒绝任何没有“currentuser”cookie 的请求。

我有这样的事情:

@Path("/users")
public class UserResource { 

      private UserService userService; 

      @GET
      @Path("/orders")
      @Produces("application/json")
      public List<Order> findOrdersOfCurrentUser() { 
            // some ugly code to access headers, extract cookies, and finally
            // extract username (a String) from a particular cookie

            return this.userService.findOrdersByUsername(username) ; 
      }
}

我想编写比这更优雅的代码。 像这样:

 @Path("/users")
 public class UserResource { 

          private UserService userService; 

          @CurrentUsername
          private String currentUser; 

          @GET
          @Path("/orders")
          @Produces("application/json")
          public List<Order> findOrdersOfCurrentUser() { 
                return this.userService.findOrdersByUsername(username) ; 
          }
    }

我对 hk2 真的很陌生,而且很难找到方法。

我只是要求实现正确的接口(或要扩展的类)。

【问题讨论】:

    标签: java dependency-injection jersey jersey-2.0 hk2


    【解决方案1】:

    您正在寻找的东西并非易事。处理此问题的一种方法是将SecurityContext 设置为ContainerRequestFilter 内的seen here。这不涉及与 HK2 的任何直接交互。然后,您可以在资源类中注入 SecurityContext。并通过

    获取用户
    securityContext.getUserPrincipal().getName();
    

    如果你真的想用自定义注释注入用户名,你需要创建一个InjectionResolverSee Defining Custom Injection Annotation。你可以注入ContainerRequestContext(同样的一个传递给@中的过滤器方法) 987654330@) 或将SecurityContext 改成InjectionResolver。例如

    过滤器

    @Provider
    @PreMatching
    public class UserFilter implements ContainerRequestFilter {
    
        public static final String USER_PROP = "user";
    
        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
            requestContext.setProperty(USER_PROP, new User("peeskillet"));
        }
    }
    

    注释

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface CurrentUser {   
    }
    

    注入解析器

    public class CurrentUserInjectionResolver implements InjectionResolver<CurrentUser> {
    
        javax.inject.Provider<ContainerRequestContext> requestContext;
    
        @Inject
        public CurrentUserInjectionResolver(
            javax.inject.Provider<ContainerRequestContext> requestContext) {
            this.requestContext = requestContext;
        }
    
        @Override
        public Object resolve(Injectee injectee, ServiceHandle<?> sh) {
            if (User.class == injectee.getRequiredType()) {
                return requestContext.get().getProperty(UserFilter.USER_PROP);
            }
            return null;
        }
    
        @Override
        public boolean isConstructorParameterIndicator() { return false; }
    
        @Override
        public boolean isMethodParameterIndicator() { return false; }
    }
    

    绑定 InjectionResolver

    @Provider
    public class UserFeature implements Feature {
    
        @Override
        public boolean configure(FeatureContext context) {
            context.register(new AbstractBinder(){
                @Override
                public void configure() {
    
                    bind(CurrentUserInjectionResolver.class)
                    .to(new TypeLiteral<InjectionResolver<CurrentUser>>(){})
                            .in(Singleton.class);
                }
            });
            return true;          
        } 
    }
    

    资源

    @Path("user")
    public class UserResource {
    
        @CurrentUser 
        private User user;
    
        @GET
        public Response getCurrentUser() {
            return Response.ok(user.getUsername()).build();
        }
    }
    

    现在我不太确定第二种方法,至少关于过滤器的部分是@PreMatching 过滤器。如果我不使其成为预匹配,User 将为空。似乎ContainerRequestContext 还没有我们设置的属性,这意味着似乎正在发生的是InjectResolver 在过滤器之前被调用。我需要调查一下。使其成为预匹配,不需要 IMO。

    不过,就我个人而言,我会采用第一种方法,只使用SecurityContext。一个完整的例子在我上面提供的链接中。通过这种方法,您可以在需要时利用 Jersey 的 RolesAllowedDynamicFeature

    【讨论】:

    • 实际上它仅适用于基于字段和构造函数的注入。它不适用于基于方法的注入和基于参数的注入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    相关资源
    最近更新 更多