9

後続の getParameter 呼び出しの結果を変更せずに、アプリケーションが POST 要求のコンテンツ/データ/本文/ペイロードを検査する必要がある状況にあります。

inputStream から本文を読み取る:

request.getInputStream本文は、 InputStream fromまたは BufferedReader fromを使用して読み取ることができますrequest.getReader

POST パラメータの読み取り:

通常、POST リクエストには、リクエストの本文にリクエスト パラメータが含まれます。これらは、 を使用して取得できますgetParameter

問題:

最初のgetParameter呼び出しは、inputStream を内部的に解析し、すべてのパラメーターをパラメーター HashMap に挿入します。解析用のコンテンツを含むためには、inputStream が必要です。したがって、コンテンツを検査することはできず、まだ getParameter 呼び出しが機能しています。

提案された (しかし十分ではない) 解決策

入力ストリームをキャッシュし、getInputStream のキャッシュを返すリクエスト ラッパーを作成します。

私はその解決策がウェブ全体で提案されているのを見てきましたが、getParameter実際には を呼び出すgetInputStreamのではなく、リクエストオブジェクトに埋め込まれた元の inputBuffer を参照しているため、機能しません。サーブレット内とフィルターを使用して試してみました

私が考えることができる唯一の解決策は、キャッシュされた入力ストリームを手動で実際に解析するように getParameter を書き直すことです。しかし、これは悪い考えのように感じます。

誰かが機能する代替手段を持っていますか? (これは Tomcat 5.5 です) これは一般的な使用例のように感じます。信じられないほど難しい。

4

2 に答える 2

1

(これはかなり古い tomcat です。より最新のものにアップグレードすることは選択肢ではないと思います。)

やりたいことは、基になる InputStream をラップする具体的な HttpServletResponse オブジェクトの構築をインターセプトする必要があります。その InputStream をプッシュバック入力ストリーム (または同等のもの) にラップする必要があります。

Tomcat 5.5 は非常に古いので、それが「通常」どのように達成されるか考えることさえできませんが、おそらく、リフレクションを使用して到達し、具体的な要求オブジェクト内の InputStream オブジェクトを交換するフィルターを作成できます。

于 2013-09-03T02:45:40.027 に答える
1

@caskey で提案されているように、考えられる解決策は、リフレクションを使用して inputBuffer を再生可能な inputbuffer に置き換えることです。しかし、私はそれがいたずらだと感じたので、そのアプローチを使用しませんでした.

代わりに、入力ストリームをバイト配列に読み取り、すべての呼び出しに対してその配列InputStreamを内部的に使用するnew を返すフィルターで要求ラッパーを作成しました。ByteArrayInputStreamgetInputStream

入力ストリームをバイト配列に読み取った後、ペイロードを解析してパラメーター マップを作成します。スーパークラスのパラメーター マップをマージして、クエリ パラメーターを使用した GET ケースをサポートしました。このパラメーター マップを使用するために、すべての getParameter*() メソッドをオーバーライドしました。

以前apache.axis.utils.IOUtils.readFullyは、ストリームをバイト配列に簡単に読み取っていました。そして、現在javax.servlet.http.HttpUtils.parsePostData、データを解析してパラメーターマップに使用しています。HttpUtils.parsePostDataは実際には推奨されていないため、見つけたらより良いバージョンに置き換える可能性があります。

しかし、これは機能します。

于 2013-09-03T07:41:24.113 に答える