我正在使用Jerse2.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非常陌生,很难找到方法去做。
我只是要求实现正确的接口(或要扩展的类)。
发布于 2015-05-04 05:04:46
你要找的不是小事。处理此问题的一种方法是将SecurityContext设置为ContainerRequestFilter中的在这里看到的。这不涉及与HK2的任何直接交互。然后,您可以在资源类中注入SecurityContext。让用户通过
securityContext.getUserPrincipal().getName();如果您真的想使用自定义注释注入用户名,则需要创建一个InjectionResolver (参见定义自定义注入注释 )。您可以将ContainerRequestContext (传递给ContainerRequestFilter中的filter方法)或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 {
}InjectionResolver
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。我需要调查这件事。使之成为预先匹配,不应要求国际海事组织。
不过,就我个人而言,我会使用第一种方法,只使用SecurityContext。我在上面提供的链接中有一个完整的例子。通过这种方法,您可以在需要时利用泽西的RolesAllowedDynamicFeature。
https://stackoverflow.com/questions/30022078
复制相似问题