Эффективный доступ к HttpServletRequest для отладочной печати.

StackOverflow https://stackoverflow.com/questions/3228276

Вопрос

Чтобы отладить неудачные запросы, я хотел бы распечатать всю информацию, поступающую из HttpServletRequest.

Теперь возможно, что запрос частично завершится неудачей (например.Несколько совпадений успешны, но одно не удалось), и в этом случае я хотел бы перехватить исключение во внутреннем методе, который не удался, напечатать ошибку + ServletUtil.toStringHttpServletRequest() и продолжить предоставление услуги (ухудшенной, но все еще полезной по сравнению сполный провал запроса).

Наша текущая реализация либо перехватывает исключение и печатает глупую информацию («getRules не удалось»), либо выдает исключение до doGet() (фактически отменяя обслуживание для пользователя), где, как и в doGet(), у меня есть доступ к HttpServletRequest, где я могу напечатайте соответствующую информацию об отладке (заголовки, параметры...).

Передача HttpServletRequest каждой функции, вызываемой во время запроса, который может потерпеть неудачу, кажется немного некрасивым, я сделаю это, если не появится другое элегантное решение.

Создание предшествующего заголовка ServletUtil.toStringHttpServletRequest() и сохранение его на карте ThreadLocal было бы расточительным как по памяти, так и по процессорному времени.По какой-то причине кажется неправильным хранить объект HttpServletRequest в ThreadLocal (пожалуйста, поправьте, если я ошибаюсь).

Информация об отладке записывается как в журнал локального компьютера, так и отправляется по электронной почте непосредственно разработчикам (отличная работа, log4j). TLSSMTPAppender), так что заходить в несколько мест будет непрактично (нужно будет собрать несколько писем, чтобы понять, что происходит), а заходить на сервер по ssh - это старость :) (у нас тут все пасмурно...сервер может не существовать к тому времени, когда я увижу ошибку)

Итак, мое решение получает доступ к PrintErrorUtility (TODO:лучше назови).Он получит (String errorMsg, Throwable t, HttpServletRequest), который напечатает ошибку вместе со всей соответствующей информацией...Это будет вызываться из внутренних блоков try {} catch, которые уведомят об ошибке, но не отменят запрос из-за нее.

Очевидно, я говорю о серверах, работающих в производстве.

Комментарии?Пожалуйста, порекомендуйте.

Спасибо, Максим.

Это было полезно?

Решение

Выполните это задание в Filter после тот FilterChain#doFilter() вызов.А ServletRequest объект уже есть.В бизнес-коде, где это исключение должно корректно подавляться, сохраните исключение как атрибут запроса и просто позвольте Filter проверьте/возьмите его из запроса.


Обновлять:согласно комментариям, вот пример:

public class Context { 
    private static ThreadLocal<Context> instance = new ThreadLocal<Context>();
    private HttpServletRequest request;
    private List<Exception> exceptions = new ArrayList<Exception>();

    private Context(HttpServletRequest request) {
        this.request = request;
        this.request.setAttribute("exceptions", exceptions);
    }

    public static Context getCurrentInstance() {
        return instance.get();
    }

    public static Context newInstance(HttpServletRequest request) {
        Context context = new Context(request);
        instance.set(context);
        return context;
    }

    public void release() {
        instance.remove();
    }

    public void addException(Exception exception) {
        exceptions.add(exception);
    }
}

И вот как использовать его в сервлете контроллера:

Context context = Context.newInstance(request);
try {
    executeBusinessCode();
} finally {
    context.release();
}

И вот как вы можете использовать его в исполняемом бизнес-коде:

} catch (Exception e) {
    Context.getCurrentInstance().addException(e);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top