3

サーブレットで生成された PDF (ByteArrayOutputStream) を PrintWriter に書き込みます。

生成された PDF ファイルを応答 PrintWriter に書き込む方法を必死に探しています。階層チェーンの上のフィルターは既に response.getWriter() を呼び出しているため、response.getOutputStream() を取得できません。

PDFを生成したByteArrayOutputStreamがあります。ここで必要なのは、この ByteArrayOutputStream の内容を PrintWriter に出力する方法だけです。誰かが私に手を差し伸べることができれば、非常に感謝しています!

4

4 に答える 4

7

他の何かがすでに を呼び出してgetWriterいる場合は、すでに何らかのテキストを応答に書き込んでいる可能性があります。その上、テキストPrintWriter用です-任意のバイナリデータを送信したい...これは間違いなく前進する方法なので、代わりに呼び出したフィルターを見つけて修正しようとします。getOutputStreamgetWriter

于 2010-04-26T11:45:22.530 に答える
0

次のようなエラーが発生していました:

この行の下には何もありませんエラー 500: java.lang.IllegalStateException: SRVE0199E: OutputStream は既に取得されています

設定で解決:

response.getOutputStream().write(bytes);
response.setContentLength(bytes.length);

出力は次のようになります。

この行の下には何もありません

于 2014-03-26T09:42:49.927 に答える
0

これはややクレイジーなアイデアですが、おそらくこのように解決します。

壊れたフィルターに本当に触れられない場合 (本当に? )、壊れたフィルターの前に配置する別のフィルターを作成します。

これは実際よりも複雑に見えますが、これは単に 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;
        }

    }
}
于 2010-04-26T13:44:31.677 に答える
0

PrintWriter のエンコーディングを知っていますか? Latin-1 の場合、単純にバイト配列を Latin-1 に変換して PrintWriter に書き込むことができます。

   String latin1 = byteStream.toString("ISO-8859-1");
   response.getWriter().write(latin1);

もちろん、これはフィルターが実際には何も書き込まないことを前提としています。

于 2010-04-26T11:51:44.370 に答える