首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >泽西和HK2 -注入当前用户

泽西和HK2 -注入当前用户
EN

Stack Overflow用户
提问于 2015-05-04 03:16:07
回答 1查看 2.1K关注 0票数 2

我正在使用Jerse2.17和HK2创建一个简单的rest应用程序。我有一个ContainerRequestFilter,它拒绝任何没有"currentuser“cookie的请求。

我有这样的事情:

代码语言:javascript
复制
@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) ; 
      }
}

我想编写一些更优雅的代码。如下所示:

代码语言:javascript
复制
 @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非常陌生,很难找到方法去做。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-04 05:04:46

你要找的不是小事。处理此问题的一种方法是将SecurityContext设置为ContainerRequestFilter中的在这里看到的。这不涉及与HK2的任何直接交互。然后,您可以在资源类中注入SecurityContext。让用户通过

代码语言:javascript
复制
securityContext.getUserPrincipal().getName();

如果您真的想使用自定义注释注入用户名,则需要创建一个InjectionResolver (参见定义自定义注入注释 )。您可以将ContainerRequestContext (传递给ContainerRequestFilter中的filter方法)或SecurityContext注入InjectionResolver。例如

过滤器

代码语言:javascript
复制
@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"));
    }
}

注解

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CurrentUser {   
}

InjectionResolver

代码语言:javascript
复制
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

代码语言:javascript
复制
@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;          
    } 
}

资源

代码语言:javascript
复制
@Path("user")
public class UserResource {

    @CurrentUser 
    private User user;

    @GET
    public Response getCurrentUser() {
        return Response.ok(user.getUsername()).build();
    }
}

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

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30022078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档