gpt4 book ai didi

java - Jersey 和 HK2 - 注入(inject)当前用户

转载 作者:行者123 更新时间:2023-11-30 07:01:12 24 4
gpt4 key购买 nike

我正在使用 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 的新手,并且很难找到实现它的方法。

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

最佳答案

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

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

如果你真的想用自定义注释注入(inject)用户名,你需要创建一个 InjectionResolver ( See Defining Custom Injection Annotation 。你可以注入(inject) ContainerRequestContext (the相同的一个传递给 ContainerRequestFilter 中的过滤器方法)或 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 {
}

注入(inject)解析器

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; }
}

绑定(bind)注入(inject)解析器

@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如果需要的话。

关于java - Jersey 和 HK2 - 注入(inject)当前用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30022078/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com