Ho difficoltà a capire il meccanismo di iniezione di Jersey. La specifica JAX-RS (http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-520005) afferma che l'iniezione tramite @Context è possibile nelle sottoclassi dell'applicazione, nelle classi di risorse radice e nei provider.Jersey @ scope scope
Ora ho una classe che viene istanziata all'avvio e ha un metodo che viene chiamato su ogni richiesta. All'interno del metodo ho bisogno di accedere all'attuale oggetto UriInfo. Il problema è che questo metodo non è chiamato dal mio codice. Quindi non posso passare UriInfo direttamente al metodo.
Io in realtà voglio fare qualcosa di simile:
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
}
}
ho provato questo. Ovviamente senza successo:
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();
}
}
L'unica soluzione che riesco a pensare è questa. Non penso sia molto pulito:
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);
}
}
Spero ci sia una soluzione migliore, ma forse sono completamente sulla strada sbagliata.
Grazie!
Forse hai solo bisogno di 'ContainerRequestFilter'? – Willy
Non so se questo funziona nella mia situazione. La specifica dice che "Le classi dei provider sono istanziate dal runtime JAX-RS". Ma ho bisogno di un riferimento all'oggetto al momento della costruzione, per passarlo al servizio di terze parti. –