繁体   English   中英

ByteArrayOutputStream到PrintWriter(Java Servlet)

[英]ByteArrayOutputStream to PrintWriter (Java Servlet)

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

我正在拼命寻找将生成的PDF文件写入响应PrintWriter的方法。 由于过滤层次结构链已经调用了response.getWriter(),因此我无法获得response.getOutputStream()。

我有一个ByteArrayOutputStream,我在其中生成PDF。 现在我需要的是一种将此ByteArrayOutputStream的内容输出到PrintWriter的方法。 如果有人能帮助我,我将非常感激!

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

你知道PrintWriter的编码是什么吗? 如果它是Latin-1,你可以简单地将字节数组转换为Latin-1并写入PrintWriter,

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

当然,这假设过滤器实际上没有写任何东西。

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

如果你真的无法触摸破碎的过滤器( 真的? ),请在破碎的过滤器之前写下另一个过滤器。

这看起来比它复杂,但这只是因为Java的冗长,所以请耐心等待。

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

因此,当你破碎的Filter调用response.getWriter() ,它将获得一个代理PrintWriter,它只在第一次实际写入时调用真实的response.getWriter()

然后,如果破坏的Filter调用response.getWriter()而不写入它就不再重要了。

我实际上没有测试过这段代码,但我相信它应该可行。

请注意,这假定破坏的Filter调用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;
        }

    }
}

我得到的错误如下:

此行下面没有错误错误500:java.lang.IllegalStateException:SRVE0199E:已获取OutputStream

通过设置解决:

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

现在输出变为:

没有这条线以下

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM