Ich habe eine schwere Zeit, den Einspritzmechanismus von Jersey zu verstehen. Die JAX-RS-Spezifikation (http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-520005) besagt, dass die Injektion über @Context in Anwendungsunterklassen, Stammressourcenklassen und Anbietern möglich ist.Jersey @Context scope
Ich habe jetzt eine Klasse, die beim Start instanziiert wird und eine Methode hat, die bei jeder Anforderung aufgerufen wird. Innerhalb der Methode brauche ich Zugriff auf das aktuelle UriInfo-Objekt. Das Problem ist, dass diese Methode nicht aus meinem Code aufgerufen wird. Also kann ich UriInfo nicht direkt an die Methode übergeben.
Ich möchte eigentlich so etwas wie dies zu tun:
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
}
}
ich dies versucht. Offensichtlich ohne Erfolg:
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();
}
}
Die einzige Problemumgehung, an die ich denken kann, ist diese. Ich glaube nicht, dass es sehr sauber ist:
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);
}
}
Ich hoffe, es gibt eine bessere Lösung, aber vielleicht bin ich völlig auf der falschen Spur.
Danke!
Vielleicht brauchen Sie nur 'ContainerRequestFilter'? – Willy
Ich weiß nicht, ob das in meiner Situation funktioniert. Die Spezifikation besagt, dass Provider-Klassen von der JAX-RS-Laufzeit instanziiert werden. Aber ich brauche einen Hinweis auf das Objekt zur Bauzeit, um es an den Third-Party-Service zu übergeben. –