java - 高效访问 HttpServletRequest 以进行调试打印

标签 java production-environment servlets debug-print

为了调试失败的请求,我想打印来自 HttpServletRequest 的所有信息。

现在,请求可能会部分失败(例如,几个匹配成功,但一个失败),在这种情况下,我想捕获失败的内部方法中的异常,打印错误+ ServletUtil .toStringHttpServletRequest() 并继续提供服务(降级但相对于完全请求失败仍然有用)。

我们当前的实现要么捕获异常并打印愚蠢的信息(“getRules failed”),要么将异常一直抛出到 doGet() (有效地取消用户的服务),就像在 doGet() 中一样,我可以访问 HttpServletRequest我可以在其中打印相关的调试信息(标题、参数...)。

将 HttpServletRequest 传递给请求期间调用的每个可能失败的函数似乎有点难看,如果没有其他优雅的解决方案出现,我会这样做。

制作一个 before head ServletUtil.toStringHttpServletRequest() 并将其存储在 ThreadLocal 映射中会浪费内存和 CPU 时间。由于某种原因,将 HttpServletRequest 对象存储在 ThreadLocal 中感觉不对(如果我错了,请纠正)。

调试信息既写入本地计算机日志,又直接通过电子邮件发送给开发人员(伟大的工作 log4j TLSSMTPAppender ),因此在多个位置进行日志记录是不切实际的(需要组合几封电子邮件才能了解发生了什么)并且 ssh'ing 进入服务器已经很老了:)(我们这里都是多云的...当我查看错误时服务器可能不存在)

所以,我的解决方案是访问“PrintErrorUtility”(TODO:更好地命名它)。这将接收 (String errorMsg, Throwable t, HttpServletRequest) ,它将打印错误以及所有相关信息...这将从内部 try {} catch block 调用,它将通知错误但不会取消请求,因为其中。

显然,我正在考虑在生产中运行的服务器。

评论?请指教。

谢谢你,马克西姆。

最佳答案

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);
    }
}

以下是如何在 Controller servlet 中使用它:

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

以下是如何在执行的业务代码中使用它:

} catch (Exception e) {
    Context.getCurrentInstance().addException(e);
}

关于java - 高效访问 HttpServletRequest 以进行调试打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3228276/

相关文章:

Java Streams - 过滤先前过滤的值

java - 如何格式化 6 或 9 位数字,如#、##、###

java - Tomcat 将所有子域转发到虚拟主机

ruby-on-rails - Webrick 作为生产服务器与 Thin 或 Unicorn?

.net-core - Dotnet 核心忽略 ASPNETCORE_ENVIRONMENT 变量

Java EE WebListener 和线程

java.io.FileNotFoundException : D:\Servers\apache-tomcat-7. 0.27\webapps\acct\accesscarddata (访问被拒绝)

eclipse - JDK/JRE/JVM/Java SDK |它们都是什么意思?有时你可以用 JRE 开发,有时你需要 JDK?

javascript - 从 Jquery Ajax 调用 servlet

css - Rails Assets 位于子目录中,无法在生产环境中加载