Получите и зарегистрируйте орган по ответу [дубликат]

Этот вопрос уже имеет ответ здесь:

У меня есть сервлет, которые обрабатывают определенные Запросы HTTP и ответы. Я хочу зарегистрировать орган по ответу прежде, чем передать обратно клиенту. Есть ли любой способ, которым я могу получить орган по ответу, прежде чем это будет, отправляют как a HttpServletResponse объект от сервлета?

29
задан BalusC 14 July 2010 в 00:47
поделиться

2 ответа

Если я правильно вас понял, вы хотите регистрировать ответ body? Это довольно дорогая задача, но если это бизнес-требование...

Как отметил @duffymo, Filter - подходящее место для этого. Вы можете перехватить тело ответа, заменив переданный ServletResponse на HttpServletResponseWrapper реализацию, которая заменяет HttpServletResponse#getWriter() на собственную реализацию, которая копирует тело ответа в некоторый буфер. После продолжения цепочки фильтров с замененным ответом, просто запишите копию в лог.

Вот пример того, как может выглядеть метод doFilter():

public void doFilter(ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException {
    final CopyPrintWriter writer = new CopyPrintWriter(response.getWriter());
    chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
        @Override public PrintWriter getWriter() {
            return writer;
        }
    });
    logger.log(writer.getCopy());
}

Вот как может выглядеть CopyPrintWriter:

public class CopyPrintWriter extends PrintWriter {

    private StringBuilder copy = new StringBuilder();

    public CopyPrintWriter(Writer writer) {
        super(writer);
    }

    @Override
    public void write(int c) {
        copy.append((char) c); // It is actually a char, not an int.
        super.write(c);
    }

    @Override
    public void write(char[] chars, int offset, int length) {
        copy.append(chars, offset, length);
        super.write(chars, offset, length);
    }

    @Override
    public void write(String string, int offset, int length) {
        copy.append(string, offset, length);
        super.write(string, offset, length);
    }

    public String getCopy() {
        return copy.toString();
    }

}

Наложите этот фильтр на url-шаблон, для которого вы хотите регистрировать ответы. Имейте в виду, что бинарный/статический контент, такой как изображения, CSS, JS файлы и т.д. не будут регистрироваться таким образом. Для их исключения достаточно url-pattern, например, *.jsp или servlet-name соответствующего сервлета. Если вы все равно хотите логировать бинарный/статический контент (в чем я не вижу никакой пользы), то вам нужно заменить HttpServletResponse#getOutputStream() таким же образом.

29
ответ дан 28 November 2019 в 01:43
поделиться

Возможно, вам поможет фильтр сервлетов. Думайте об этом как об аспектно-ориентированном программировании для HTTP.

3
ответ дан 28 November 2019 в 01:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: