有效访问HttpServletRequest以进行调试打印

时间:2010-07-12 11:59:49

标签: java production-environment servlets debug-print

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

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

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

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

创建一个前置头ServletUtil.toStringHttpServletRequest()并将其存储在ThreadLocal映射中将在内存和CPU时间上浪费。出于某种原因,在ThreadLocal中存储HttpServletRequest对象是错误的(如果我错了,请更正)。

调试信息被写入本地机器日志并直接通过电子邮件发送给开发人员(Great work log4j TLSSMTPAppender),因此登录几个地方将不切实际(需要汇总几封电子邮件才能了解正在发生的事情) on)和ssh'ing到服务器是老年:):我们在这里多云...当我看到错误时服务器可能不存在)

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

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

评论?请指教。

谢谢你,Maxim。

1 个答案:

答案 0 :(得分:0)

在<{em> 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);
    }
}

以下是如何在控制器servlet中使用它:

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

以下是您在执行的业务代码中使用它的方法:

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