2013-05-12 11 views
6

古くなったベンダーAPIをラップするRESTful Webサービスを作成しています。いくつかの外部構成が必要となり、ファイルまたはrdbmsのいずれかでサーバーに格納されます。私はGlassfish 3.1.2でJersey 1.11.1を使用しています。この構成データは、すべてString Key/Value形式です。Jersey/Glassfishにグローバル変数をロードして保存するには

私の最初の質問はこれです.Jerseyにグローバル変数とインスタンス変数を保存して、要求間で永続化され、すべてのリソースで利用できるようにするにはどうすればいいですか?これが純粋なサーブレットアプリケーションであれば、これを達成するためにServletContextを使用します。

質問の2番目の部分は、Jerseyサーバーがロードされたらどのように設定を読み込むことができるのですか?ここでも、私のサーブレットの類推は、init()メソッドと同等のものを見つけることです。

答えて

11

@Singleton @Startup EJBが要件に一致しています。

@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:追加注釈グラハムさんのコメント

+0

これは素晴らしいソリューションのように見え、ロード時に正しく実行されますが、リソースクラスでこのEJBを参照しようとするとInvocationTargetException(コンテナによってNullPointerExceptionと表示されます)が表示されます。 – Graham

+0

Jerseyのメーリングリストから:リソースをマネージドBeanに変換しない限り、EEリソースのデフォルト注入はサポートされません(リソースクラスをマネージドBeanに変換するときにいくつかの制約があることに注意してください)。_ – Graham

+0

@私のリソースへのステートレスフラグは、これは完全に動作し、間違いなく素晴らしい解決策です。これらの2つのページは、私がコンセプトをもっとよく理解する助けになりました:[EJB 3.1とREST - 軽量ハイブリッド](http://www.adam-bien.com/roller/abien/entry/ejb_3_1_and_rest)[Singletons](https ://blogs.oracle.com/kensaks/entry/singletons) – Graham

7

あなたは、Webアプリケーションの開始前に、変数や属性としてコンテキストに設定初期化のために、以下のようなものをlistenerを使用することができます。

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 
     ... 
    } 

} 

このリスナーはweb.xmlに設定されています。

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

あなたはServletContextを注入し、属性を取得するための@Contextアノテーションを使用することができます。

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

あたり、これは間違いなく可能な解決策であるが、それは私は現在フィルタリングするために何もしても、いくつかの余分な仕事を持っていないのweb.xmlを加えることを含みますServletContextに存在するその他の属性私はこれをアップフォートにしましたが、よりシンプルで多目的なので、他のポストへの答えを授与しなければなりませんでした。 – Graham

関連する問題