簡體   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