2012-04-17 3 views
9

私はタイトルをここにフレーズする方法を正確には分かりません。そのために、私は答えを探すためにどうやってどうやって行くのか本当に分かりません。Javaにリクエストコンテキストがありますか?

私はリクエストを処理するjavaサーブレットエンジンを持っています。我々はdoGetメソッドの要求を持っていると言う:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    //set up user data 

    //do whatever the user requested 
    SomeClass c = new SomeClass(); 
    c.doSomething(); 
} 

今のdoSomethingで、私は要求を行ったユーザがアクセスできるようにしたいです。これにより

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    //set up user data 
    MyUserObj userObj = new MyUserObj(); 
    userObj.setId('123'); 

    //do whatever the user requested 
    SomeClass c = new SomeClass(userObj); 
    c.doSomething(); 
} 

が、私はMyUserObjのインスタンスへのアクセスを持って、それがさらに必要に応じて一緒に渡すことができます。今、私は、Javaオブジェクトを作成し、私は必要な場所に渡すことでそれをやっています。

これは不快です。 asp.net MVC3で(私は現在、それを学んでいる、私はJavaを学び始めた後に始まったが、これは本当に便利だと私はどのようにJavaでそれをやっていたか再考させた)私は、例えば、現在のアイテムを格納することができますこのようなスレッド:HttpContext.Current.Items.Add("myId", "123")HttpContextは、私がオブジェクトの周りを回らなくても他の機能で利用できます。

オブジェクトをパラメータとして渡さずに、要求ごとにいくつかの変数を設定する(またはMyUserObjectを後でアクセスするように設定する)方法はありますか?

これはすでによくある質問ですが、正しい方法で私を指差してください。私はそれをどのようにフレーズするかわかりませんでした。

+0

私はあなたのタイトルを編集する自由を取った。それが良いかどうかを確認してください。 – Bozho

+0

私は明示的にそれを渡しています。暗黙の状態と依存関係は保守性の点で悪いです。 Springのようなフレームワークは、これを明示的に行うことで定型文の一部を取り除き、混乱させる助けとなるはずです。 – millimoose

+0

私の質問を理解していれば、あなたのタイトルの編集が私の元のタイトルよりも良いと信じています:) – Two13

答えて

19

サーブレットAPIにはありませんが、自分で簡単に作ることができます。 (spring-mvcのようないくつかのフレームワークは、strutsはそのような機能を提供します)

オブジェクトを保存して取得するのにpublic static ThreadLocalを使用してください。 HttpServletRequest自体をスレッドローカルに格納し、そのsetAttribute()/getAttribute()メソッドを使用することもできますし、スレッドローカルをMapとして保存することもできます。サーブレットAPIには関係ありません。重要な注意点は、リクエスト後にスレッドローカルをクリーンアップする必要があることです(たとえば、Filterを使用)。

また、オブジェクトをパラメータとして渡す方が、通常はWebレイヤからサービスレイヤに渡すため、Web関連オブジェクトに依存しないようにすることをお勧めします(HttpContextなど)。

あなたはむしろ周りに渡すよりも、スレッドローカルに保存する罰金であると判断した場合:

public class RequestContext { 
    private static ThreadLocal<Map<Object, Object>> attributes = new ThreadLocal<>(); 
    public static void initialize() { 
     attributes.set(new HashMap<Map<Object, Object>>()); 
    } 
    public static void cleanup() { 
     attributes.set(null); 
    } 
    public static <T> T getAttribute(Object key) { 
     return (T) attributes.get().get(key); 
    } 
    public static void setAttribute(Object key, Object value) { 
     attributes.get().put(key, value); 
    } 
} 

し、必要なフィルタ:

@WebFilter(urlPatterns="/") 
public class RequestContextFilter implements Filter { 
    public void doFilter(..) { 
     RequestContext.initialize(); 
     try { 
      chain.doFilter(request, response); 
     } finally { 
      RequestContext.cleanup(); 
     } 
    } 
} 
+2

'ServletRequest.setAttribute'について? –

+2

その後、リクエストを渡す必要があります。私はそれがOPが望んでいるものではないと仮定します。私はオプションとして追加しましたが、まだスレッドローカルが必要です。 – Bozho

+0

ああ、良い点、 'HttpContext.Current'との類似点はありません。 –

4

あなたがオブジェクトを添付することができます現在のリクエストにsetAttributeで送信します。このAPIは主に内部ルーティングに使用されますが、属性名に適切な名前空間を使用する限り、独自の目的でも安全に使用できます。

+0

私はパラメータとしてServletRequestオブジェクトを渡す必要がありますか? – Two13

+0

あなたはそうです。しかし、あなたがリクエストを渡す場合は、他のリクエスト関連オブジェクトを回避することができます。 – ataylor

関連する問題