これはややクレイジーなアイデアですが、おそらくこのように解決します。
壊れたフィルターに本当に触れられない場合 (本当に? )、壊れたフィルターの前に配置する別のフィルターを作成します。
これは実際よりも複雑に見えますが、これは単に Java の冗長性によるものなので、ご容赦ください。
基本的にそれが行うことは、フィルターとチェーンでそれに続くサーブレットHttpServletResponseWrapper
をラップ/「オーバーライド」するために使用することです。response.getWriter()
したがって、壊れた Filter が を呼び出すと、代わりに、実際に最初に書き込まれたときにresponse.getWriter()
のみ real を呼び出すプロキシ PrintWriter が取得されます。response.getWriter()
response.getWriter()
その後、破損した Filter が書き込みなしで呼び出しても問題ありません。
このコードを実際にテストしたことはありませんが、動作するはずです。
response.getWriter()
これは、壊れた Filter が実際に何かを書き込むことなく呼び出すことを前提としていることに注意してください。壊れたフィルターが何かを書き込んでから、それに PDF を書き込もうとすると、とにかく出力が壊れます。
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
public class BrokenWriterGetterFixingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, final ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest, new BrokenWriterGetterFixingResponseWrapper((HttpServletResponse) servletResponse));
}
@Override
public void destroy() {
}
private static class BrokenWriterGetterFixingResponseWrapper extends HttpServletResponseWrapper {
public BrokenWriterGetterFixingResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(new BrokenWriterGetterFixingWriter(getResponse()));
}
}
private static class BrokenWriterGetterFixingWriter extends Writer {
private PrintWriter responseWriter;
private final ServletResponse response;
public BrokenWriterGetterFixingWriter(ServletResponse response) {
this.response = response;
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
getResponseWriter().write(cbuf, off, len);
}
@Override
public void flush() throws IOException {
getResponseWriter().flush();
}
@Override
public void close() throws IOException {
getResponseWriter().close();
}
private PrintWriter getResponseWriter() throws IOException {
if (null == responseWriter) {
responseWriter = response.getWriter();
}
return responseWriter;
}
}
}