ByteArrayOutputStream to PrintWriter (сервлет Java) - PullRequest
3 голосов
/ 26 апреля 2010

Запись сгенерированного PDF (ByteArrayOutputStream) в сервлете в PrintWriter.

Я отчаянно ищу способ записать сгенерированный файл PDF в ответ PrintWriter. Так как фильтр по иерархической цепочке уже вызвал response.getWriter (), я не могу получить response.getOutputStream ().

У меня есть ByteArrayOutputStream, где я сгенерировал PDF в. Теперь все, что мне нужно, - это способ вывода содержимого этого ByteArrayOutputStream в PrintWriter. Если бы кто-нибудь мог помочь мне, я был бы очень признателен!

Ответы [ 4 ]

7 голосов
/ 26 апреля 2010

Если что-то еще уже называлось getWriter, возможно, оно уже записало некоторый текст в ответ. Кроме того, PrintWriter предназначен для текста - вы хотите отправить произвольные двоичные данные ... getOutputStream, безусловно, путь вперед, поэтому я постараюсь найти фильтр, который имеет позвонить getWriter и исправить это вместо этого.

0 голосов
/ 26 марта 2014

Я получаю сообщение об ошибке:

ничего ниже этой строки. Ошибка 500: java.lang.IllegalStateException: SRVE0199E: OutputStream уже получен

Решено настройкой:

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

Теперь вывод становится:

ничего ниже этой строки

0 голосов
/ 26 апреля 2010

Вот несколько сумасшедшая идея, но я бы, наверное, решил ее следующим образом.

Если вы действительно не можете дотронуться до сломанного фильтра ( правда? ), напишите другой фильтр, который вы поместите перед сломанным фильтром.

Это выглядит сложнее, чем есть, но это только из-за многословия Java, поэтому, пожалуйста, потерпите меня.

В основном он использует HttpServletResponseWrapper для переноса / "переопределения" response.getWriter() в фильтрах и сервлета, следующего за ним в цепочке.

Поэтому, когда ваш неработающий Фильтр вызывает response.getWriter(), он вместо этого получает прокси PrintWriter, который вызывает только действительный response.getWriter() при первом его записи.

Тогда уже не имеет значения, если сломанный Фильтр вызывает 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;
        }

    }
}
0 голосов
/ 26 апреля 2010

Знаете ли вы, что такое кодировка PrintWriter? Если это Latin-1, вы можете просто преобразовать байтовый массив в Latin-1 и записать в PrintWriter,

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

Конечно, это предполагает, что фильтр на самом деле ничего не пишет.

...