[英]Jersey and HK2 - Injecting current user
我正在使用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真的很陌生,並且真的很難找到方法。
我只是在要求正確的接口來實現(或擴展類)。
您正在尋找的東西並非易事。 解決此問題的一種方法是在ContainerRequestFilter
內設置SecurityContext
,如此處所示 。 這不涉及與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
為null。 看來ContainerRequestContext
還沒有我們設置的屬性,這意味着正在發生的情況是在過濾器之前調用了InjectResolver
。 我將需要對此進行調查。 使其成為預匹配項,不需要IMO。
但是就我個人而言,我會采用第一種方法,僅使用SecurityContext
。 我上面提供的鏈接中有一個完整的示例。 通過這種方法,您可以根據需要利用Jersey的RolesAllowedDynamicFeature
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.