HTTP サーブレット リクエストは、一度読み取った後に POST 本文からパラメータを失います
この状況では、POST リクエストを処理するときに次のことを理解することが重要です、パラメータは通常、リクエスト本文で送信されます。デフォルトでは、サーブレット コンテナはパラメータに初めてアクセスしたときに入力文字ストリームまたはバイナリ ストリームを消費します。その結果、フィルタ チェーン内のその後のアクセス試行は失敗します。
この問題を解決するには、考慮すべき主なアプローチが 2 つあります。
1.インターセプター コンポーネント:
フィルター チェーンを使用する代わりに、インターセプター コンポーネントを利用できます。これらのコンポーネントはアスペクトを使用して実装でき、消費されたリクエストの InputStream に依存せずに解析されたリクエスト本体の操作を可能にします。このアプローチは、独自のモデル オブジェクトを作成するためにリクエストの InputStream が 1 回だけ解析されるため、通常はより効率的です。
2. HttpServletRequestWrapper:
HTTP 層でフィルター チェーンが優先される場合、HttpServletRequestWrapper を拡張することが効果的な方法です。この手法には、リクエストの InputStream の消費とバイトのキャッシュが含まれます。
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper { private ByteArrayOutputStream cachedBytes; public MultiReadHttpServletRequest(HttpServletRequest request) { super(request); } @Override public ServletInputStream getInputStream() throws IOException { if (cachedBytes == null) cacheInputStream(); return new CachedServletInputStream(cachedBytes.toByteArray()); } @Override public BufferedReader getReader() throws IOException{ return new BufferedReader(new InputStreamReader(getInputStream())); } private void cacheInputStream() throws IOException { /* Cache the inputstream in order to read it multiple times. For * convenience, I use apache.commons IOUtils */ cachedBytes = new ByteArrayOutputStream(); IOUtils.copy(super.getInputStream(), cachedBytes); } /* An input stream which reads the cached request body */ private static class CachedServletInputStream extends ServletInputStream { private final ByteArrayInputStream buffer; public CachedServletInputStream(byte[] contents) { this.buffer = new ByteArrayInputStream(contents); } @Override public int read() { return buffer.read(); } @Override public boolean isFinished() { return buffer.available() == 0; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener listener) { throw new RuntimeException("Not implemented"); } } }
元のリクエストをフィルタ チェーンに渡す前に MultiReadHttpServletRequest でラップすることで、リクエストの本文を複数回読み取ることができます。このソリューションでは、getParameterXXX メソッドによる複数の読み取りも容易になることに注意してください。
編集:
ServletInputStream インターフェイスの新しいバージョンでは、isReady や setReadListener などの追加メソッドを使用する必要があります。実装されました。詳細については、この質問を参照してください。
以上がHTTP サーブレット リクエストで 1 回の読み取り後に POST ボディ パラメータが失われるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。