2009-12-04 16 views
12

Javaコードで要求オブジェクトを取得する必要があります。特定の理由により、このオブジェクトを自分のコードに渡すことはできません。私は何かを言うことができる方法はありますか:getCurrentHTTPServletRequestJavaコードからHttpServletRequest(要求)オブジェクトを取得

私がサーブレットコンテキストにいると仮定することは安全です。

+0

は* * *は、*なぜ*詳しく説明してください:いない場合は、このJVMパラメータを追加することによって、それを有効にする必要があります正しい方法。半擬似コード/ sscceを投稿することで、達成しようとしていることの写真を得ることができます。 – BalusC

+0

SolrRequestを受け入れるSolr QueryComponentを拡張する必要があります。残念ながら、SolrRequestはサーブレットリクエストのラッパーではありません。 SolrDispatchFilter(フィルターだけでなく要求を処理するために使用されます)は、HttpServletRequestからSolrRequestへの変換を行います。したがって、私のカスタムQueryComponentにリクエストから余分な情報を渡す唯一の方法は、やりたくないSolrDispatchFilterを変更することです。 お世話になりました。 ThreadLocal変数は私の仕事をするはずです。 – aseem

答えて

17

あなたはとする必要がある場合はに渡す必要があります。あなたがしていることは、基本的には醜いものになるでしょう。

を使用すると、ThreadLocal変数が使用されます。基本的には、リクエストを取得したときにそのスレッドのコンテキストを設定し、後でフェッチします。これは、スレッドを処理しているスレッド内の要求を取得する必要があるかぎり、あなたがファンキーな非同期要求処理をしない限り、動作します。しかし、まさにそのような理由から、脆いです。

しかし、私は強くにあなたの依存関係を明示するようお勧めします。サーブレットリクエストを下に渡すか、必要なビットだけを渡します。

+4

+1:*のためにそれを渡す必要があります*。私が本当にリクエストスレッドとして使用しない醜いThreadLocalハックよりもはるかに推奨されているのは、ウェブコンテナによってプールされることができます。あるいは、終了時にスレッドから確実に削除する必要があります。あまりにも多くの作業と厄介な副作用/ – BalusC

+3

オブジェクトを渡すことは必ずしも可能ではありません。あなたはコントロールできないAPIをいくつかクロスしなければならないかもしれません。任意のAPIを変更することができたとしても、すべてのメソッドでリクエスト引数を宣言し、メソッドを呼び出すたびにリクエストオブジェクトを渡すことは愚かで不便です。あなたがやっていることを知っている限り、ThreadLocalは問題ありません。 – irreputable

+1

それから、APIは、小規模な目的のために意図されていないか、間違った方向の解決策を探しています。他の側から* *アクセスするのはどうですか?私は、JSP/Servletをあまりにも長くして、十分な方法があることを確認しました。そして、これには必ずしもThreadLocalが必要なわけではありません。 – BalusC

0

ビジネス関連の理由から最上位のサーブレットが実際にはタブーになっていると仮定すると、依然としてリクエストをプレビューしてThreadLocalに埋め込むためにServletFilterを定義するオプションがあります。 web.xmlもまた奇形ではないと仮定します。

しかし、私はこれが非常に醜いであろうという点でJon Skeetに同意します。私はこれをコード化し、別の仕事を見つけようとします。 :)

実際には、フィルターが受信サーブレットから完全に制御を奪ってしまうことを考えれば、このテクニックを使って自分のサーブレットにコードを行き渡らせ、必要なものを実行してから、 、 "公式の"サーブレット、またはそれらの行に沿ったものが含まれます。これらのソリューションの中には、リクエストデータを正確かつ確実に処理できるものもあります。

4

Jon Skeetは事実上すべてを言っていますが、彼のアドバイスには「あなたが必要とするビットだけ」という明確な説明が1つあります。

そしてThreadLocalオプションのビットを拡張 - あなたはすべての着信要求を処理し、フィルタには注意してくださいあなたが要求ごとにそれを設定しているので

public final static ThreadLocal<HttpServletRequest> httpServletRequestTL = 
     new ThreadLocal<HttpServletRequest>(); 

で要求を(設定Filterを持つことができますマッピング)では、サーブレットコンテナスレッドプールについて心配する必要はありません。常にの現在のリクエストがあります。リクエスト。

P.S.これはskaffmanによって提案された春のユーティリティの背後にあるロジックです - 私は彼があなた自身のものを作るのではなく、安定したコンポーネントを推薦します。

9

要求オブジェクトをコールスタックに渡すことができないと仮定すると、何らかの種類の共有メカニズムが必要になります。これは理想的ではありませんが、時には必要な場合もあります。

Springは、ちょうどこの目的のためにRequestContextFilterを提供します。これはThreadLocalを使用し、コードでRequestContextHolder経由で現在の要求を取得できるようにします。

Servlet 2.3 Filter that exposes the request to the current thread, through both LocaleContextHolder and RequestContextHolder. To be registered as filter in web.xml.

This filter is mainly for use with third-party servlets, e.g. the JSF FacesServlet. Within Spring's own web support, DispatcherServlet's processing is perfectly sufficient.

あなたはむしろにおける忍び寄るリスクのバグよりも、既存の、ワーキング溶液を、使用することをお勧めし、その後、ThreadLocalを使用するつもりなら:このフィルタは春の他の部分を使用する必要はないことに注意してくださいこのコードはThreadLocalです。

4

これを行うサーブレットAPIはありません。しかし、Tomcatは、これを行うためのAPIコールを提供してい

HttpServletRequest request = (HttpServletRequest)org.apache.catalina.core.ApplicationFilterChain.getLastServicedRequest(); 

この現在のスレッドからのサービス提供のためにサーブレットに渡された最後の要求を取得します。

この機能を有効にするには、Tomcatが「厳密なサーブレット準拠」モードになっている必要があります。あなたがこれを必要とする*、我々はこれを行う方法をより良い提案をポップするとき

org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true 
+0

これは私が直面している状況に対する最も近い答えです。あなたが興味があれば、私はそれのための恩恵を作りました。基本的には、サーブレットコンテキストからSpringサービスファクトリオブジェクトを取得するフィルタがあります。このファクトリは、フィルタがgetServiceメソッドを呼び出すときにBeanのインスタンスを割り当てますが、セッションまたはリクエストの実際のhttpServletRequestオブジェクトを渡す必要があります。しかし、フィルターを所有しているリモートサービスブリッジの抽象化を壊すので、私はそうしてはいけません。あなたの答えは正しいようですが、問題はWebAppが複数のユーザーであり、間違った要求で終了する可能性があることです。 – Jigzat

+0

私は必要なもののように見えますが、そのような場合は "java.lang.IllegalAccessError:org/apache/catalina/core/ApplicationFilterChain"を取得します。 – Laloutre

関連する問題