Trudno mi zrozumieć mechanizm wtryskiwania Jersey. Specyfikacja JAX-RS (http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-520005) stwierdza, że wstrzykiwanie przez @Context jest możliwe w podklasach aplikacji, klasach zasobów źródłowych i dostawcach.Jersey @Context zakres
Mam teraz klasę, która jest tworzona przy uruchomieniu i ma metodę, która jest wywoływana na każde żądanie. Wewnątrz metody potrzebuję dostępu do bieżącego obiektu UriInfo. Problem polega na tym, że ta metoda nie jest wywoływana z mojego kodu. Więc nie mogę przekazać UriInfo bezpośrednio do metody.
I rzeczywiście chcą zrobić coś takiego:
public class MyClass implements ThirdPartyInterface {
// not possible because class is no Application subclass, root resource class or provider
@Context
private UriInfo uriInfo;
public void methodCallebByThirdPartyCode() {
Uri requestUri = uriInfo.getRequestUri();
// do something
}
}
próbowałem tego. Oczywiście bez powodzenia:
public class MyClass implements ThirdPartyInterface {
private UriInfo uriInfo;
public MyClass(UriInfo uriInfo) {
this.uriInfo = uriInfo;
}
public void methodCallebByThirdPartyCode() {
Uri requestUri = uriInfo.getRequestUri();
// do something
}
}
@Provider
@Produces(MediaType.WILDCARD)
public class MyBodyWriter implements MessageBodyWriter<MyView> {
@Context
private UriInfo uriInfo;
private MyClass myClass;
private ThirdPartyClass thirdPartyClass;
public MyBodyWriter() {
// uriInfo is null at this time :(
myClass = new MyClass(uriInfo);
thirdPartyClass = new ThirdPartyClass();
thirdPartyClass.register(myClass);
}
public void writeTo(final MyView view, final Class<?> type, /* and so on */) throws IOException, WebApplicationException {
// execute() calls MyClass#methodCallebByThirdPartyCode()
thirdPartyClass.execute();
}
}
Jedyne obejście, jakie mogę wymyślić, to jest to. Nie sądzę, że to jest bardzo czyste:
public class MyClass implements ThirdPartyInterface {
private UriInfo uriInfo;
public void setUriInfo(final UriInfo uriInfo) {
this.uriInfo = uriInfo;
}
public void methodCallebByThirdPartyCode() {
Uri requestUri = uriInfo.getRequestUri();
// do something
}
}
@Provider
@Produces(MediaType.WILDCARD)
public class MyBodyWriter implements MessageBodyWriter<MyView> {
@Context
private UriInfo uriInfo;
private MyClass myClass;
private ThirdPartyClass thirdPartyClass;
public MyBodyWriter() {
myClass = new MyClass();
thirdPartyClass = new ThirdPartyClass();
thirdPartyClass.register(myClass);
}
public void writeTo(final MyView view, final Class<?> type, /* and so on */) throws IOException, WebApplicationException {
myClass.setUriInfo(uriInfo);
// execute() calls MyClass#methodCallebByThirdPartyCode()
thirdPartyClass.execute();
myClass.setUriInfo(null);
}
}
Mam nadzieję, że istnieje lepsze rozwiązanie, ale być może jestem na niewłaściwym torze.
Dzięki!
Może po prostu potrzebujesz 'ContainerRequestFilter'? – Willy
Nie wiem, czy to działa w mojej sytuacji. Specyfikacja mówi, że "klasy dostawcy są tworzone przez środowisko wykonawcze JAX-RS". Ale potrzebuję odniesienia do obiektu w czasie budowy, aby przekazać go do usługi strony trzeciej. –