2013-05-12 13 views
6

Tworzę usługę RESTful Web Service, która otacza przestarzały API dostawcy. Niektóre zewnętrzne konfiguracje będą wymagane i będą przechowywane na serwerze w pliku lub rdbms. Używam oprogramowania Jersey 1.11.1 w programie Glassfish 3.1.2. Te dane konfiguracyjne są w formacie klucza/wartości String.Jak ładować i przechowywać globalne zmienne w Jersey/Glassfish

Moje pierwsze pytanie brzmi: gdzie mogę przechowywać zmienne globalne/instancje w Jersey, aby były one przechowywane między żądaniami i dostępne dla wszystkich zasobów? Gdyby to była czysta aplikacja Serwletu, użyłbym ServletContext, aby to osiągnąć.

Druga część pytania brzmi, w jaki sposób mogę załadować konfigurację po załadowaniu serwera Jersey? Znowu moja analogia z Servletem będzie znaleźć odpowiednik metody init().

Odpowiedz

11

@Singleton @Startup EJB odpowiada Twoim wymaganiom.

@Singleton 
@Startup // initialize at deployment time instead of first invocation 
public class VendorConfiguration { 

    @PostConstruct 
    void loadConfiguration() { 
     // do the startup initialization here 
    } 

    @Lock(LockType.READ) // To allow multiple threads to invoke this method 
         // simultaneusly 
    public String getValue(String key) { 
    } 
} 


@Path('/resource') 
@Stateless 
public class TheResource { 
    @EJB 
    VendorConfiguration configuration; 
    // ... 
} 

EDIT: Dodany adnotacji zgodnie komentarzu Grahama

+0

To wygląda na świetne rozwiązanie i działa poprawnie w czasie ładowania, ale otrzymuję wyjątek InvocationTargetException (wyświetlany przez kontener jako obiekt NullPointerException), gdy próbuję odwołać się do tego komponentu EJB w moich klasach zasobów. – Graham

+0

Z listy mailingowej w Jersey: _By domyślny wtrysk zasobów EE nie jest obsługiwany, chyba że zmienisz zasób w zarządzany komponent bean (i zauważ, że istnieją pewne ograniczenia podczas przekształcania klasy zasobów w zarządzany komponent bean) ._ – Graham

+0

Po dodaniu @Stateless flag to my resources to działało idealnie i jest zdecydowanie doskonałym rozwiązaniem. Te dwie strony pomogły mi też lepiej zrozumieć pojęcia: [EJB 3.1 AND REST - LEKKIE HYBRYD] (http://www.adam-bien.com/roller/abien/entry/ejb_3_1_and_rest) [Singletons] (https : //blogs.oracle.com/kensaks/entry/singletons) – Graham

7

Można użyć listener dla init zmiennych i ustawione w kontekście jako atrybutu przed rozpoczęciem aplikacji internetowych, coś jak następuje:

package org.paulvargas.shared; 

import java.util.HashMap; 
import java.util.Map; 

import javax.servlet.ServletContext; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 

public class LoadConfigurationListener implements ServletContextListener { 

    public void contextInitialized(ServletContextEvent sce) { 
     // read file or rdbms 
     ... 
     ServletContext context = sce.getServletContext(); 
     // set attributes 
     ... 
    } 

    public void contextDestroyed(ServletContextEvent sce) { 
     ServletContext context = sce.getServletContext(); 
     // remove attributes 
     ... 
    } 

} 

Ten słuchacz jest skonfigurowany w web.xml.

<listener> 
    <listener-class>org.paulvargas.shared.LoadConfigurationListener</listener-class> 
</listener> 

Można użyć @Context adnotacji dla wstrzyknąć ServletContext i pobierania atrybut.

package org.paulvargas.example.helloworld; 

import java.util.*; 

import javax.servlet.ServletContext; 
import javax.ws.rs.*; 
import javax.ws.rs.core.*; 

@Path("/world") 
public class HelloWorld { 

    @Context 
    private ServletContext context; 

    @GET 
    @Produces("text/plain; charset=UTF-8") 
    public String getGreeting() { 

     // get attributes 
     String someVar = (String) context.getAttribute("someName") 

     return someVar + " says hello!"; 
    } 

} 
+0

Jest to z pewnością wykonalne rozwiązanie, ale wymaga dodawania web.xml gdzie obecnie mam nikogo, a także kilka dodatkowych prac w celu odfiltrowania pozostałe atrybuty istniejące w ServletContext. Podjąłem tę kwestię, ale musiałem udzielić odpowiedzi na drugie stanowisko, ponieważ jest to zarówno prostsze, jak i bardziej wszechstronne. – Graham