これは非常に刺激的な問題です。私が数回処理しなければならなかったものと、満足できる解決策を見つけたことのないものがあります。
基本的な問題は、サーブレットAPIがここで役に立たないということです。そのため、あなたはそれを騙さなければなりません。私の解決策は、getWriter()メソッドとgetOutput()メソッドをオーバーライドし、バッファにデータをキャプチャするHttpServletResponseWrapperのサブクラスを記述することです。キャプチャしたいJSPのURIにリクエストを転送し、元のレスポンスをラッパーレスポンスに置き換えます。その後、バッファからデータを抽出し、操作し、最終結果を元の応答に書き戻します。
public class CapturingResponseWrapper extends HttpServletResponseWrapper {
private final OutputStream buffer;
private PrintWriter writer;
private ServletOutputStream outputStream;
public CapturingResponseWrapper(HttpServletResponse response, OutputStream buffer) {
super(response);
this.buffer = buffer;
}
@Override
public ServletOutputStream getOutputStream() {
if (outputStream == null) {
outputStream = new DelegatingServletOutputStream(buffer);
}
return outputStream;
}
@Override
public PrintWriter getWriter() {
if (writer == null) {
writer = new PrintWriter(buffer);
}
return writer;
}
@Override
public void flushBuffer() throws IOException {
if (writer != null) {
writer.flush();
}
if (outputStream != null) {
outputStream.flush();
}
}
}
このようなものになることができ、それを使用するコード:
はここでこれを行うに私のコードです
HttpServletRequest originalRequest = ...
HttpServletResponse originalResponse = ...
ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
CapturingResponseWrapper responseWrapper = new CapturingResponseWrapper(originalResponse, bufferStream);
originalRequest.getRequestDispatcher("/my.jsp").forward(originalRequest, responseWrapper);
responseWrapper.flushBuffer();
byte[] buffer = bufferStream.toByteArray();
// now use the data
それは非常に醜いですが、それは私が見つけた最高のソリューションです。疑問に思っている場合、サーブレットの仕様には、転送時やオリジナルの使用、またはラップされたバージョンの要求や応答オブジェクトを完全に入れ替えることができないため、ラッパー応答に元の応答が含まれている必要があります。
+1私をビートしてください。 –
私はみんな同じぞっとするような解決策を持っていると感じます。 – skaffman
これは良いアプローチです。 「フィルタ」指向のアプローチのようなもの。 しかし、この問題には2つの問題があります。 1.これをスタンドアロンシステムとして実行することはできません。例えば。あなたが行うことはできません: main(){compileJSP()} 2.これをフィルターコード内で使用すると、一部のアプリケーションサーバーはrequestwrapperの状態をニックピッキングしています。私は不正な状態を取得する傾向があり、 JSPは文字列にレンダリングする(本質的に私がこれを行うときは決して簡単ではない)。 しかし、確かにそれは良い解決策です。 –