Подтвердить что ты не робот

Где объекты @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 )
4b9b3361

Ответ 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 &lt > 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 выше. Полученная коллекция доступна только для чтения.