为了调试失败的请求,我想打印来自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。
答案 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);
}