Ich bin derzeit Refaktorierung einer Jersey Web App und möchte einige cross-cutting Bedenken in ihren eigenen Klassen bündeln und Annotationen verwenden, um Methoden abzufangen. Zum Beispiel gibt es viele Methoden, bei denen ich prüfen muss, ob der Benutzer der Eigentümer der Entität ist, die er ändern möchte (in meinem Fall ist dies ein Projekt). Daher muss ich innerhalb des Interceptors Datenbankaufrufe durchführen und obwohl die entsprechenden DAOs injiziert werden, wäre dies der beste Weg.@Inject funktioniert nicht in MethodInterceptor verwaltet von HK2
Derzeit meine Abfangjäger sieht wie folgt aus:
public class ProjectOwnerCheckInterceptor implements MethodInterceptor {
@Inject
private EntityManager em;
@Inject
private UserProvider userProvider;
@Inject
private RMUserDAO rmUserDAO;
@Inject
private ProjectDAO projectDAO;
public ProjectOwnerCheckInterceptor() {
// TODO Auto-generated constructor stub
}
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// First of all let's get the annotation
ProjectOwnerCheck check = arg0.getMethod().getAnnotation(ProjectOwnerCheck.class);
// if there is no check, then just proceed!
if (check == null)
arg0.proceed();
long projectId = (long) arg0.getArguments() [check.projectIdIndex()];
// Handling ownership!!
Project project = getProjectOrThrow(projectId);
return arg0.proceed();
}
}
Die benutzerdefinierte Anmerkung gerade nach vorne ist. Ich brauche ein paar kleine Informationen, die Argumentposition der EntityID in dem Verfahren ist als Anzahl von Parametern und Typen überprüfen muss hinzufügen variieren:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface ProjectOwnerCheck {
int projectIdIndex() default -1;
}
Für Jersey/HK2 zu wissen, was mit den Abfangjäger zu tun, die ich geschaffen habe ein Filter Umsetzung InterceptionService:
public class HK2InterceptorFilter implements InterceptionService {
private final static MethodInterceptor PROJECT_CHECK_METHOD_INTERCEPTOR = new ProjectOwnerCheckInterceptor();
private final static List<MethodInterceptor> PROJECT_CHECK_METHOD_LIST = Collections
.singletonList(PROJECT_CHECK_METHOD_INTERCEPTOR);
public HK2InterceptorFilter() {
// TODO Auto-generated constructor stub
}
@Override
public Filter getDescriptorFilter() {
return BuilderHelper.allFilter();
}
@Override
public List<MethodInterceptor> getMethodInterceptors(Method method) {
if (method.isAnnotationPresent(ProjectOwnerCheck.class))
return PROJECT_CHECK_METHOD_LIST;
return null;
}
@Override
public List<ConstructorInterceptor> getConstructorInterceptors(Constructor<?> constructor) {
// TODO Auto-generated method stub
return null;
}
}
ich diese Filter in meiner JerseyApplication Klasse bin Bindung:
register(new AbstractBinder() {
@Override
protected void configure() {
try {
bind(HK2InterceptorFilter.class).to(InterceptionService.class).in(Singleton.class);
bind(getPasswordStorage()).to(PasswordStorage.class);
bind(getDocumentService()).to(DocumentService.class);
bind(UserManagementAccessor.getUserProvider()).to(UserProvider.class);
} catch (Exception e) {
throw new InternalServerErrorException(e);
}
}
});
Wenn Sie einen Haltepunkt in meinem Interceptor gesetzt Ich kann sehen, dass es richtig instanziiert ist und die Methode gots aufgerufen hat. Aber was ich total vermisse, sind all die @Inject-Felder, die ich haben muss, um meinen Check zu machen. Fehle ich etwas oder ist das in HK2 nicht möglich? Ich habe mit Guice gearbeitet und dort funktioniert es (ich bin - aufgrund der Tatsache, dass die Code-Basis der App ziemlich groß ist, aber zeitlich begrenzt - an HK2 gebunden :)).
Vielen Dank für Ihre Hilfe im Voraus!
PS:
I Jersey bin mit 2,17
Dies löste es !! VIELEN DANK!! – Inkvine