Где объекты @Context приходят из
Я искал везде, но не могу найти четкого ответа...
Каков механизм, посредством которого сервер (стеклянная рыба для моей проблемы) вводит фактические объекты, которые аннотируются с помощью @Context? Более конкретно, если бы я хотел написать класс, который сделал что-то вроде:
@Path("/")
public class MyResource {
@GET
public String doSomething(@Context MyObject obj) {
// ...
}
}
то как бы я это сделал? Где находится объект MyObject, кто это делает, и как?
Изменить: я видел такие вещи, как:
Использование @Context, @Provider и ContextResolver в JAX-RS
http://jersey.576304.n2.nabble.com/ContextResolver-confusion-td5654154.html
Однако это не соответствует тому, что я видел, например. в конструкторе org.neo4j.server.rest.web.RestfulGraphDatabase, который имеет следующую подпись:
public RestfulGraphDatabase(
@Context UriInfo uriInfo,
@Context Database database,
@Context InputFormat input,
@Context OutputFormat output,
@Context LeaseManager leaseManager )
Ответы
Ответ 1
Вы можете написать своего собственного поставщика инъекций и подключить его к Джерси - посмотрите SingletonTypeInjectableProvider и PerRequestTypeInjectableProvider - продлить один из этих классов (в зависимости от жизненного цикла, который вы хотите для инъекционного объекта) и зарегистрировать свою реализацию в качестве поставщика в своем веб-приложении.
Например, что-то вроде этого:
@Provider
public class MyObjectProvider extends SingletonTypeInjectableProvider<Context, MyObject> {
public MyObjectProvider() {
// binds MyObject.class to a single MyObject instance
// i.e. the instance of MyObject created bellow will be injected if you use
// @Context MyObject myObject
super(MyObject.class, new MyObject());
}
}
Чтобы включить поставщика в ваше веб-приложение, у вас есть несколько вариантов:
- Если ваше приложение использует сканирование классов (или сканирование пакетов), просто убедитесь, что поставщик находится в правильном пакете/в пути к классам
- или вы можете просто зарегистрировать его, используя запись META-INF/services (добавьте файл META-INF/services/com.sun.jersey.spi.inject.InjectableProvider, имеющий имя вашего класса поставщика в нем)
Ответ 2
Я думаю, что могу быть на что-то... и если это сработает, Мартин должен получить частичный кредит.:)
Похоже, что класс @Provider должен реализовать интерфейс com.sun.jersey.spi.inject.Injectable < > T > . Однако я не уверен, что этого достаточно, чтобы на самом деле был добавлен @Context. Что не хватает, так это то, что мы должны сообщить объекту ResourceConfig веб-приложения о @Provider. В контексте того, что я пытаюсь сделать, и принимая подсказки от neo4j-сервера, оставшаяся работа сводится к:
- расширение com.sun.jersey.spi.container.servlet.ServletContainer и переопределение метода configure:
@Override
protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa)
{
super.configure( wc, rc, wa );
Set<Object> singletons = rc.getSingletons();
singletons.add(new MyObjectProvider());
}
- указав, что этот контейнер должен использоваться в дескрипторе развертывания web.xml:
<servlet>
<servlet-name>JAX-RS Servlet Container</servlet-name>
<servlet-class>com.blah.MyServletContainer</servlet-class>
</servlet>
Ответ 3
Я не думаю, что вы можете использовать @Context
с пользовательским типом типа MyObject
. Это для инъекций типов, которые jax-ws уже понимает. Здесь указано здесь.
В главе 5 спецификации JAX-RS представлены все стандартные типы Java JAX-RS, которые могут использоваться с @Context.
Скорее всего, вы захотите использовать что-то вроде @FormParam
или @PathParam
. См. раздел 2.3 спецификации для описания. Вот ваш ответ, скопированный из этой части спецификации:
В общем, тип Java параметра метода может:
- Будьте примитивным типом;
- У конструктора, который принимает один аргумент String,
- Имейте статический метод с именем valueOf или fromString, который принимает единственный аргумент String (см., например, Integer.valueOf(String) и java.util.UUID.fromString(String)); или
- Список, Set или SortedSet, где T удовлетворяет 2 или 3 выше. Полученная коллекция доступна только для чтения.
Ответ 4
Смотрите главы 5-6 спецификации JAX-RS. Это должно рассказать вам все, что вам нужно знать об этом.