当前位置: 首页 > 面试题库 >

jersey和HK2-正在注入当前用户

鲁博赡
2023-03-14
问题内容

我正在使用jersey 2.17和HK2创建一个简单的rest应用。我有一个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真的很陌生,并且真的很难找到方法。

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


问题答案:

您要找的不是一件容易的事。解决此问题的一种方法是在SecurityContext内部设置ContainerRequestFilter,如此处所示。这不涉及与HK2的任何直接交互。然后,您可以将注入到SecurityContext资源类中。并吸引用户

securityContext.getUserPrincipal().getName();

如果你真的想要去一个自定义注释注入的用户名,您将需要创建一个InjectionResolver(请参阅定义定制注塑注释。你可以注入ContainerRequestContext(同一个,传递给在过滤法ContainerRequestFilter)或SecurityContextInjectionResolver。例如

过滤

@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则将为null。似乎ContainerRequestContext还没有我们设置的属性,这意味着似乎正在发生的是InjectResolver在过滤器之前调用。我将需要对此进行调查。使其成为预赛者,不需要IMO。

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



 类似资料:
  • null 所以我创建了SFFactory类并在ApplicationConfig中注册它。 Sffactory.java ApplicationConfig.java

  • 将EntityManager注入资源可以工作,但不能注入Callable。在这里,EntityManager保持。 请告知代码保存在这里是否比保存在GitHub上更好。

  • 试图创建一个自定义的,我可以通过Jersey注入到我的资源中。 这在本问题的Java中有涉及。我已经阅读了有关这方面的文档,这些文档也是用Java编写的。最后,GitHub中的一些代码涵盖了相同的主题(通过Dropwizard完成)。 这将全部编译,但在运行时失败,出现以下异常 我不知道是我在向Scala的转换中犯了错误,还是我在注册绑定器时做了错误的事情。

  • 我正在尝试将 HttpServlet 请求注入到我的泽西岛资源类中。我得到错误“”。我使用的是 Java 8。 据我所知,我正在做一个完全普通的球衣应用程序。以下是全部代码: 它阻塞了@Context HttpServletRequest部分。如果我将HttpServletRequest设置为一个字段,它将自动失败,请求为空。 以下是依赖关系。jersey.version为2.27: 这是完整的堆

  • 我正在尝试使用Jersey测试框架为我的REST API编写功能测试。然而,当我在功能测试中使用依赖注入时,我似乎遇到了一个障碍。我的主应用程序看起来是这样的: 是否有一种方法可以将HK2服务定位器与Jersey测试框架一起使用,或者我是否需要将我的应用程序视为外部容器并使用外部容器提供程序,如这里所述:外部容器? 此外,由于这些是功能测试,因此在这里不允许对注入的服务进行嘲弄。

  • 问题内容: 我有一个使用JPA持久性的jersey-2 / hk2应用程序。将在这样的约束启动 工厂级的 这可行,但是对于每个请求,我都会在日志中收到有关已注册EntityManager的警告: 我究竟做错了什么?在jersey-2 / hk2应用程序中初始化EntityManager的正确方法是什么? 问题答案: 一种选择是不是创建一个新的(这是在请求范围内),您可以创建为一个单独的工厂,然后就