2012-06-05 19 views
12

Szukałem wszędzie, ale nie wydaje się znaleźć jednoznacznej odpowiedzi ...Gdzie @Context obiekty pochodzą z

Jaki jest mechanizm, dzięki któremu serwer (GlassFish dla mojego problemu) wstrzykuje rzeczywiste objets które są opatrzone adnotacją @Context? Dokładniej, gdybym chciał napisać klasę, która zrobiła coś takiego:

@Path("/") 
public class MyResource { 
    @GET 
    public String doSomething(@Context MyObject obj) { 
    // ... 
    } 
} 

, a następnie jak to zrobić? Gdzie znajduje się obiekt MyObject, kto to robi i jak?

Edit: Widziałem rzeczy, jak następuje:

Using @Context, @Provider and ContextResolver in JAX-RS

http://jersey.576304.n2.nabble.com/ContextResolver-confusion-td5654154.html

Jednak to nie pogodzić z tym, co widziałem, na przykład w konstruktorze org.neo4j.server.rest.web.RestfulGraphDatabase, który posiada następujący podpis:

public RestfulGraphDatabase(
    @Context UriInfo uriInfo, 
    @Context Database database, 
    @Context InputFormat input, 
    @Context OutputFormat output, 
    @Context LeaseManager leaseManager) 

Odpowiedz

7

Możesz napisać własną dostawcy wtrysku i podłączyć to pod Jersey - look at SingletonTypeInjectableProvider i PerRequestTypeInjectableProvider - rozszerzenie jednej z tych klas (w zależności od cyklu życia chcesz dla obiektu iniekcji) i zarejestrować swoją implementację jako dostawca w Twojej aplikacji internetowej.

Na przykład coś takiego:

@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()); 
    } 
} 

Aby dołączyć dostawcy w aplikacji internetowej masz kilka opcji:

  1. jeśli aplikacja korzysta skanowanie ścieżce klasy (lub skanowanie pakietów) po prostu zrobić upewnij się, że dostawca znajduje się we właściwym pakiecie/na ścieżce klasy
  2. lub możesz po prostu zarejestrować go przy użyciu wpisu META-INF/services (dodaj plik META-INF/services/com.sun.jersey.spi.inject.InjectableProvider z opcją imię twojego zaopatrzenia Klasa er w jego zawartość)
+0

Jeśli jesteś podklasy javax.ws.rs.core.Application, możesz zarejestrować dostawcę za pomocą 'this.getSingletons(). add (new MyObjectProvider());' w swoim konstruktorze aplikacji. – justin

+0

Linki są zerwane. –

+0

Wypróbuj te: https://jersey.java.net/nonav/apidocs/1.19/jersey/com/sun/jersey/spi/inject/SingletonTypeInjectableProvider.html https://jersey.java.net/nonav/apidocs /1.19/jersey/com/sun/jersey/spi/inject/PerRequestTypeInjectableProvider.html – elanh

-1

Zobacz chapters 5-6 of the JAX-RS spec. To powinno ci powiedzieć wszystko, co musisz wiedzieć na ten temat.

+0

Czy dokumenty te powiedzieć jak napisać taki funkcjonalność siebie? Które zrozumiałem było pytanie. –

+0

Ty nie. Dotyczy komponentów szkieletowych. Jeśli chcesz iniekcji zależności, poszukaj kontenera DI, takiego jak Spring. –

+0

Czy odpowiedzi na linki nie są mile widziane, skoro zawartość strony z linkami może się zmienić? – smcg

0

Nie sądzę, aby można było używać @Context z typem zdefiniowanym przez użytkownika, takim jak MyObject. Jest przeznaczony do wstrzykiwania typów, które jax-ws już rozumie. Wspomniano o nim here.

Chapter 5 specyfikacji JAX-RS przedstawia wszystkie standardowe typy Java JAX-RS, które mogą być używane z @Context.

Zamiast tego prawdopodobnie użyjesz czegoś takiego jak @FormParam lub @PathParam. Zobacz section 2.3 specyfikacji dla opisu. Oto odpowiedź, skopiowane z tej części specyfikacji:

W ogólnym typu Java parametru metoda może:

  1. być prymitywny typ;
  2. Mieć konstruktor, który akceptuje pojedynczy argument String;
  3. Mieć statyczną metodę o nazwie valueOf lub fromString, która akceptuje pojedynczy argument String (zobacz, na przykład, Integer.valueOf (String) i java.util.UUID.fromString (String)); lub
  4. Lista, zestaw lub posortowane, gdzie T spełnia 2 lub 3 powyżej. Wynikowa kolekcja jest tylko do odczytu.
+0

Prawidłowo. Możesz wstrzyknąć tylko 12 dozwolonych instancji obiektów wymienionych tutaj: https://readlearncode.com/java-ee/what-is-javax-ws-rs-core-context-httpheaders-and-uriinfo/ – Alex

3

myślę mogę być na coś ... a jeśli to działa, Martin powinien dostać częściowy kredyt. :)

Wydaje się, że klasa @Provider musi implementować T> interfejs com.sun.jersey.spi.inject.Injectable <. Jednak nie jestem pewien, czy to wystarczy, aby rzeczywiście wstrzyknąć @Context. Brakuje nam tego, że musimy powiedzieć obiektowi ResourceConfig aplikacji internetowej o @Provider. W kontekście tego, co próbuję zrobić, biorąc wskazówek z neo4j-serwer, pozostała praca sprowadza się do:

  • rozszerzenie com.sun.jersey.spi.container.servlet.ServletContainer, i przesłanianie Sposób konfiguracje:
@Override 
protected void configure(WebConfig wc, ResourceConfig rc, WebApplication wa) 
{ 
    super.configure(wc, rc, wa); 
    Set<Object> singletons = rc.getSingletons(); 
    singletons.add(new MyObjectProvider()); 
} 
  • określa, że ​​pojemnik ten może być stosowany w deskryptorze web.xml:
<servlet> 
    <servlet-name>JAX-RS Servlet Container</servlet-name> 
    <servlet-class>com.blah.MyServletContainer</servlet-class> 
</servlet> 
+1

Och, nie - nie musisz tego robić. Edytowałem swoją odpowiedź, aby pokazać, jak zarejestrować dostawcę. –

Powiązane problemy