То, что вы ищете, не является тривиально выполненным. Один из способов справиться с этим - установить SecurityContext
внутри ContainerRequestFilter
, как seen here. Это не предполагает прямого взаимодействия с HK2. Затем вы можете ввести SecurityContext
в свой класс ресурсов. И заставить пользователь по
securityContext.getUserPrincipal().getName();
Если вы действительно хотите идти с инъекционным именем пользователя с помощью пользовательской аннотации, вам нужно будет создать InjectionResolver
(See Defining Custom Injection Annotation. Вы можете придать ContainerRequestContext
(тот же один передаются метода фильтра в 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 {
}
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
, если это необходимо.
это было здорово! работал как шарм – justatester
на самом деле он работает только для инъекций на основе полей и конструкторов. он не работает для инъекций, основанных на методе, и не на основе параметров. – justatester
http://stackoverflow.com/a/30426226/2587435 –