1

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

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

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

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

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

调试信息被写入本地机器日志并直接通过电子邮件发送给开发人员(伟大的工作 log4j TLSSMTPAppender),因此在几个地方登录是不切实际的(需要组合几封电子邮件以了解发生了什么)和 ssh'ing服务器已经老了:)(我们这里都是阴天......当我看到错误时服务器可能不存在)

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

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

评论?请指教。

谢谢你,马克西姆。

4

1 回答 1

0

在调用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);
}
于 2010-07-12T12:07:15.267 回答