Возможно ли прочитать тело ответа в весенней загрузке? - PullRequest
0 голосов
/ 04 октября 2019

У меня PrintWriter из HttpServletResponse, и я хотел бы знать, есть ли какой-нибудь способ прочитать его буфер (учитывая, что HttpServletResponse.getWriter() PrintWriter не очищается автоматически).

Я знаю, что есть несколько способов преобразовать InputStream в OutputStream через InputStream.transferTo(), но есть ли способ сделать это другим способом и преобразовать мой PrintWriter в любой тип OutputStream? Или есть какой-то способ просто прочитать тело ответа HttpServletResponse?

До сих пор я пробовал метод toString(), который не перезаписывается. Я попытался передать его через разные потоки, такие как PipedInputStream и ByteArrayOutputStream.

Кстати, я использую архитектуру микропроцессоров с весенней загрузкой.

1 Ответ

0 голосов
/ 05 октября 2019

Наконец-то я нашел способ справиться с этим с помощью пружинной загрузки Filter путем переопределения HttpServletResponseWrapper. так вот мой код (класс, который переопределяет HttpServletResponseWrapper, чтобы изменить поток вывода ответа по умолчанию на мой пользовательский ServletOutputStream):

public class HttpServletResponseCopier extends HttpServletResponseWrapper {

    private ServletOutputStreamCopier copier;
    private ServletOutputStream outputStream;
    private PrintWriter writer;

    /**
     * @param response
     */
    public HttpServletResponseCopier(HttpServletResponse response) {
        super(response);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException
    {
        if (outputStream != null)
            throw new IOException("output stream already called for this response");
        else {
            outputStream = getResponse().getOutputStream();
            copier = new ServletOutputStreamCopier(this.outputStream);
            return copier;
        }
    }

    @Override
    public PrintWriter getWriter() throws IOException
    {
        if (outputStream != null)
            throw new IOException("print writer already called for this response");
        else {
            outputStream = getResponse().getOutputStream();
            copier = new ServletOutputStreamCopier(outputStream);
            writer = new PrintWriter(new OutputStreamWriter(copier, getResponse().getCharacterEncoding()));
            return writer;
        }
    }

    @Override
    public void flushBuffer() throws IOException
    {
        if (writer != null)
            writer.flush();
        else if (copier != null)
            copier.flush();

    }

    public String getContent()
    {
        String content = "";
        try {
            content = IOUtils.toString(copier.getCopyBuffer(), getResponse().getCharacterEncoding());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content;
    }

}

и мой класс ServletOutputStreamCopier (класс, который копирует содержимоепоток в ByteArrayOutputStream):

public class ServletOutputStreamCopier extends ServletOutputStream {

    private ServletOutputStream outputStream;
    private ByteArrayOutputStream copier;

    /**
     * 
     */
    public ServletOutputStreamCopier(ServletOutputStream outputStream) {
        super();
        this.outputStream = outputStream;
        this.copier = new ByteArrayOutputStream();
    }

    @Override
    public boolean isReady()
    {
        return this.outputStream.isReady();
    }

    @Override
    public void setWriteListener(WriteListener listener)
    {

    }

    @Override
    public void write(int b) throws IOException
    {
        if (this.copier == null)
            this.copier = new ByteArrayOutputStream();
        if (this.outputStream == null)
            throw new IOException("outputStream is null");
        this.copier.write(b);
        this.outputStream.write(b);

    }

    public byte[] getCopyBuffer()
    {
        return this.copier.toByteArray();
    }

}

и, наконец, вставить его в загрузочный фильтр пружины:

@Component
public class LoggingFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(
        HttpServletRequest request,
        HttpServletResponse response,
        FilterChain filterChain
    ) throws ServletException, IOException
    {
        HttpServletResponseCopier responseWrapper = new HttpServletResponseCopier(response);
        filterChain.doFilter(request, responseWrapper);

        System.out.println("response body: "+responseWrapper.getContent());

    }
}

, который выводит это:

"body": <response body here>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...