14

(ここでタイトルをどのように表現するか正確にはわかりません。そのため、答えを検索する方法もよくわかりません。)

リクエストを処理する 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()、どのユーザーがリクエストを行ったかにアクセスできるようにしたいと考えています。現在、メソッド内に Java オブジェクトを作成し、必要な場所に渡すことでそれを行っています。

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できるようになり、必要に応じてアプリケーションでさらに渡すことができます。

ASP.NET MVC3 では、現在のスレッドの項目/属性を次のように保存することでこれを達成できることを知っています HttpContext.Current.Items.Add("myId", "123")HttpContextその後、オブジェクトを明示的に渡す必要なく、他の関数で使用できます。

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

4

2 に答える 2

22

サーブレット API にはありませんが、非常に簡単に独自のものを作成できます。(spring-mvc のような一部のフレームワーク、struts はそのような機能を提供します)

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

また、オブジェクトをパラメーターとして渡すことは、より良い方法と見なされることに注意してください。通常は、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();
         }
     }
}
于 2012-04-17T18:43:10.357 に答える
5

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

于 2012-04-17T18:50:39.507 に答える