2017-05-24 7 views
0

他のサーブレットには見えないが、サーブレットAIでAとBは、HashMapを作成し、initでサーブレットコンテキストに保存する()ので、のような:のServletContext変数のは、私は2つのサーブレットがあるとしましょう

ServletContext context = getServletContext(); 
context.setAttribute("otable", someObject); 

今でサーブレットBのinit()私は、サーブレット・コンテキスト・オブジェクト(私は最初のweb.xmlを経由して最初に起動するサーブレットコンテキストオブジェクトを作成し、サーブレットを指定しています)へのローカル参照初期化しています:私は、その後の挿入とサイズ

// get and set reference to object cache 
oc = (ObjectCache)getServletContext().getAttribute("otable"); 

をサーブレットAが再び呼び出され、サーブレットコンテキストHashMaをチェックするとpの場合、サイズはまだ0です。

サーブレットコンテキストオブジェクトへのローカル参照を格納するのは悪い考えですか?サーブレットのコンテキストからオブジェクトを直接取得しようとしましたが、同じ結果が得られました。私はここで何が欠けていますか?共有オブジェクトを作成します

サーブレットは、次のと私のweb.xmlで最初に開始されます。

<servlet> 
<servlet-name>ServletA</servlet-name> 
<servlet-class>package.ServletA</servlet-class> 
<load-on-startup>0</load-on-startup> 
</servlet> 
+0

わかりました。ありがとうMarkus、ただ好奇心が強いですが、その場合、サーブレットのローカル変数はサーブレットのコンテキストと同じではありませんか?あるいは、同じサーブレットの複数のインスタンスに対してサーブレット・コンテキストが使用されていますか? 2つのサーブレットにまたがって配置するために並行ハッシュマップを使用する際の問題はありますか? – fobius

+0

私のコメントは間違っていたので削除しました、ごめんなさい! –

+0

サーブレットが初期化されていますか?起動時に負荷を設定できます。それ以外の場合は、最初の要求が到着するまで初期化されません。はい、間違いなく同時アクセスが必要な場合はHashMapを使用しないでください。それは競争状態に終わるかもしれません! –

答えて

0

のServletContextにアプリケーション全体のオブジェクト別名クロスサーブレットを格納するという考えは完全に実行可能です。私はあなたのアプローチを再テストし、それは完全に正常に動作します。コード内で投稿するのを忘れてしまった何かを逃さなければなりません。以下のように私はそれを動作させることができ

ServletA(中略):

public void init() throws ServletException { 
    Map<String, String> map = new ConcurrentHashMap<>(); 
    getServletContext().setAttribute("map", map); 
    System.out.println("Servlet A Mapsize: " + map.size()); 
    map.put("foo", "bar"); 
    System.out.println("Servlet A Mapsize: " + map.size()); 
} 

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    Map<String, String> map = (Map<String, String>) getServletContext().getAttribute("map"); 
    System.out.println("Servlet A Mapsize: " + map.size()); 
} 

ServletB(中略):

public void init() throws ServletException { 
    Map<String, String> map = (Map<String, String>) getServletContext().getAttribute("map"); 
    System.out.println("Servlet B Mapsize: " + map.size()); 
    map.put("foo", "bar"); 
    System.out.println("Servlet B Mapsize: " + map.size()); 
} 

のweb.xml(中略):

<servlet> 
    <servlet-name>ServletA</servlet-name> 
    <servlet-class>mypackage.ServletA</servlet-class> 
    <load-on-startup>0</load-on-startup> 
</servlet> 
<servlet> 
    <servlet-name>ServletB</servlet-name> 
    <servlet-class>mypackage.ServletB</servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>ServletA</servlet-name> 
    <url-pattern>/a</url-pattern> 
</servlet-mapping> 

アプリケーションを起動すると、あなたの次の出力:

サーブレットA Mapsize:0

サーブレットA Mapsize:1

サーブレットB Mapsize:1

サーブレットB Mapsize:1

として、あなたが見ることができる、地図は正しく埋まっています。

これで、servletAを呼び出して、すべて正常かどうかをチェックできます。ブラウザで

オープン(私の設定):ところで1

、:

http://localhost:8080/servtest/a

は、次のように出力

サーブレットA Mapsizeを生成します。利用可能なCDIがあれば、よりメンテナンス可能なコードのためのapplicationScopedキャッシュプロデューサ

関連する問題