3

将 Servlet 中生成的 PDF (ByteArrayOutputStream) 写入 PrintWriter。

我正在拼命寻找一种将生成的 PDF 文件写入响应 PrintWriter 的方法。由于层次链上的过滤器已经调用了 response.getWriter(),所以我无法得到 response.getOutputStream()。

我确实有一个 ByteArrayOutputStream,我在其中生成了 PDF。现在我需要的只是一种将这个 ByteArrayOutputStream 的内容输出到 PrintWriter 的方法。如果有人能帮我一把,将不胜感激!

4

4 回答 4

7

如果已经调用了其他东西getWriter,它很可能已经在响应中写入了一些文本。此外,PrintWriter用于文本- 你想发送任意二进制数据......getOutputStream绝对是前进的方向,所以我会尝试找到调用getWriter并修复它的过滤器。

于 2010-04-26T11:45:22.530 回答
0

这是一个有点疯狂的想法,但我可能会这样解决。

如果您真的无法触摸损坏的过滤器(真的吗?),请在损坏的过滤器之前编写另一个过滤器。

这看起来比实际复杂,但这只是因为 Java 的冗长,所以请多多包涵。

基本上它所做的是它用于在过滤器HttpServletResponseWrapper中包装/“覆盖”response.getWriter()以及在链中跟随它的 servlet。

因此,当您损坏的 Filter 调用response.getWriter()时,它将改为获得一个代理 PrintWriter ,该代理仅response.getWriter()在第一次实际写入时才调用 real 。

response.getWriter()那么如果损坏的过滤器调用而不写入它就不再重要了。

我还没有实际测试过这段代码,但我相信它应该可以工作。

请注意,这假定损坏的过滤器调用response.getWriter()而没有实际编写一些东西。如果损坏的过滤器写了一些东西,然后您也尝试向其写入 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 回答
0

我收到如下错误:

此行下方没有任何内容错误 500: java.lang.IllegalStateException: SRVE0199E: OutputStream 已获得

通过设置解决:

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

现在输出变为:

这条线以下没有

于 2014-03-26T09:42:49.927 回答