У меня есть трудное понимание механизма впрыска Джерси. Спецификация JAX-RS (http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-520005) гласит, что инъекция через @Context возможна в подклассах приложений, корневых классов ресурсов и поставщиков.Jersey @Context scope
У меня теперь есть класс, который создается при запуске и имеет метод, который вызывается для каждого запроса. Внутри метода мне нужен доступ к текущему объекту UriInfo. Проблема в том, что этот метод не вызывается из моего кода. Поэтому я не могу передать UriInfo непосредственно методу.
Я действительно хочу сделать что-то вроде этого:
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
}
}
Я попробовал это. Очевидно, что без успеха:
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();
}
}
Единственное обходное решение, о котором я могу думать, это. Я не думаю, что это очень чистый:
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);
}
}
Я надеюсь, что есть лучшее решение, но, может быть, я полностью на ложном пути.
Спасибо!
Возможно, вам просто нужен 'ContainerRequestFilter'? – Willy
Я не знаю, работает ли это в моей ситуации. В спецификации указано, что «классы-поставщики создаются при помощи среды выполнения JAX-RS». Но мне нужна ссылка на объект во время строительства, чтобы передать его третьей стороне службы. –