2012-02-19 12 views
2

この問題は本当にうんざりしており、そのためのベストプラクティスを見つけることができません。例の問題点に、私は明確にしてみましょう:カスタムクラスファイル内のJava WebのHttpServletRequest/Responseオブジェクトへのアクセス

私のような静的メソッドがあります:あなたは、私がリクエストとレスポンスオブジェクトにアクセスする必要が見ることができると私はHttpServletRequestを/レスポンスを渡したくないと

public class AppError { 
    public static void systemError(string errorMsg) { //Like "Can't connect to DB" 
     HttpServletRequest request = ?????????? "HOW TO ACCESS?"; 
     request.setAttribute("Error", errorMsg); 
     request.getRequestDispatcher("/error.jsp").forward(request, response(????????)); 
    } 
} 

をこれは、AppError.systemErrorが呼び出された場所を渡すことを意味し、ファイル、Cookie、ユーザー操作、データベース操作の読み取り/書き込みなど多くの場所です。

私は解決策が見つかったと思います。それはFilterと保存されたリクエストとレスポンスのオブジェクトで使用されますが、その後Filter.Destroy()メソッドを使用してThreadLocal変数を解放しますThreadLocal.remove()メソッドは、デバッグモードでテストしたときに呼び出されません。これは、スレッドが決して解放されないことを意味します。

ServletContextオブジェクト内の要求オブジェクトと応答オブジェクトにアクセスする方法が見つからないため、ServletContextListernerも解決策ではありません。私はServletContext.getRequest()のようなメソッドを期待しましたが、何もありません。

私はJSFも使用していますが、JSFの問題はFacesContextにもカスタムクラスではアクセスできません。またJSFはリスナーより遅くロードされているので、FacesContextを使用してリクエストおよび応答オブジェクトを取得すると、エラー・システムをリスナーで使用できません。

ここでベストプラクティスは何ですか?私はこれが明確な問題であることを意味し、私はこれを解決せずに進めることはできません。

Btw、エラーメソッドが例です。要求オブジェクトと応答オブジェクトにアクセスするために必要な場所があります。

答えて

4

基本的に、正しく設定されたフィルタがスレッドローカルストレージ(TLS)と組み合わせて機能しない理由はありません。

キー洞察はFilter#Destroy()方法でTLSをクリアすることではなく、メインのフィルタリングチェーンの後にfinally句で:

@WebFilter(filterName="requestTLSFilter") 
public class RequestTLSFilter extends Filter { 

    private static final ThreadLocal<ServletRequest> THREAD_LOCAL = new ThreadLocal<ServletRequest>(); 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { 
     try { 
      THREAD_LOCAL.put(request); 
      chain.doFilter(request, response); 
     } finally { 
      THREAD_LOCAL.remove(); 
     } 
    } 

    // Other methods  
} 

JSFに関しては、FacesContext.getCurrentInstance()はどこでも使用可能です。 JSFはそれを誰が呼んでいるかについての暗黙の知識は持っていませんが、Faceletsサーブレットが呼び出された後でコールチェーン内のコードでしか利用できません。

もう1つの方法があります。私は、しようと、最終的れるFilterChainとそのようにそのためのおかげで使用することができます知らなかった

HttpServletRequest request = (HttpServletRequest) PolicyContext.getContext("javax.servlet.http.HttpServletRequest"); 
+0

:あなたのコンテナはコンテナ用のJavaの許可契約(JACC)をサポートしている場合は、次はあなただけでなく、現在の要求を取得しますアイデアArjan Tijmsは完全に問題を解決しました! – Seregwethrin

関連する問題