1

Tomcat 6で実行されているStrutsに基づくアプリケーションでHTTPPOSTリクエストの生の本体をログに記録しようとしています。SOに関する以前の投稿が1つ見つかりましたが、受け入れられたソリューションが正しく機能しません。場合。問題は、特定の場合にのみPOST本文をログに記録し、ログ記録後にStrutsに本文からパラメーターを解析させることです現在、私が書いたフィルターでは、HttpServletRequestWrapperオブジェクトから本文を読み取ってログに記録できますが、その後、Strutsは解析するパラメーターを見つけることができないため、DispatchAction呼び出し(要求のパラメーターの1つに依存します)は失敗します。

StrutsとTomcatのソースコードを調べたところ、POST本体をバイト配列に格納し、その配列に基づいてStreamとReaderを公開するかどうかは問題ではないことがわかりました。パラメータを解析する必要がある場合、TomcatのRequestオブジェクトは、その時点ですでに読み取られている内部InputStreamにアクセスします。

この種のロギングを正しく実装する方法を知っている人はいますか?

4

3 に答える 3

2

実際、Strutsはパラメーターを解析せず、サーブレットコンテナーに依存して解析します。そして、コンテナがinputStreamを読み取ってパラメータMapを作成すると、もちろん、読み取るものは何も残っていません。また、Tomcatの実装では、最初にinputStreamを読み取ると、getParameter *ファミリーのメソッドは、getInputStreamまたはgetReaderを使用せず、最適化されたリーダーに内部的にアクセスするため、作業する必要がありません。したがって、ServletRequestWrapperの唯一の解決策は、getInputStream、getReader、およびStrutsがパラメーターの読み取りに依存するgetParameter*ファミリーをオーバーライドすることです。おそらく、org.apache.catalina.util.RequestUtilを見て、POST本体の解析部分を複製しないようにすることができます。

于 2010-03-21T14:48:33.217 に答える
0

フィルタで行う必要があるのは、投稿の内容全体を読んでから、リクエストをチェーンに渡すときに行うことです。独自の入力ストリームをバックアップします。たとえば、ディスク上のファイルへの投稿を読んでから、次のように呼び出します。

chain.doFilter(new ServletRequest() {}, response);

クラスのほとんどのメソッド呼び出しを元のリクエストに委任できますが、入力ストリームを開くときは、ディスク上のファイルから読み取る必要があります。

これは非常に頻繁に呼び出され、誤って実行すると害を及ぼす可能性があるため、リソースをリークしないようにする必要があります。

于 2010-03-15T17:37:19.117 に答える
0

質問にリンクされたフィルターの例は見栄えがよく、機能するはずです。たぶん、Strutsディスパッチャーフィルターのweb.xml で定義しているのかもしれません。その場合、リクエストの本文を解析してログに記録し、Strutsで利用できるようにするのは実際には遅すぎます。Strutsディスパッチャーフィルターのにこのフィルターを宣言する必要があります。フィルタの順序は重要です。で定義されている順序で呼び出されますweb.xml

于 2010-03-15T18:10:52.973 に答える