2010-07-12 72 views
1

为了调试失败的请求,我想打印来自HttpServletRequest的所有信息。高效访问HttpServletRequest以进行调试打印

现在,请求可能会部分失败(例如,几个匹配成功,但一个失败),在这种情况下,我想捕获内部方法失败的异常,打印错误+ ServletUtil.toStringHttpServletRequest()并继续提供服务(降级但仍然有用与完成请求失败)。我们当前的实现捕获异常并打印哑信息(“getRules失败”)或一直抛出异常doGet()(有效地取消用户服务),因为在doGet()中我可以访问HttpServletRequest,我可以在相关的调试信息(标题,参数...)中打印。

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

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

调试信息被写入本地机器日志,并通过电子邮件直接发送给开发人员(伟大的工作log4j TLSSMTPAppender),所以在多个地方登录将是不实际的(将需要组装几封电子邮件,以了解发生了什么)和进入服务器ssh'ing是年龄较大:)(我们都在这里多云...服务器可能不存在的时间,我看看错误)

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

很明显,我正在关注生产中的服务器。

评论?请指教。马克西姆。

谢谢你,马克西姆。

回答

0

在调用FilterChain#doFilter()后,在Filter中执行此任务。 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); 
} 
+0

好的,但为了在请求属性中存储异常,我需要访问请求对象,是不是它使我们回到方形1? (除非我错过了什么,在这种情况下请纠正我的错误)编辑:我会传递一个 2010-07-12 12:23:09

+0

您使用的是特定的MVC框架还是本地的MVC框架?大多数现有MVC框架都有一个threadlocal上下文,您可以从中获取“底层”原始请求/响应对象 – BalusC 2010-07-12 12:40:58

+0

没有MVC,它是一个后端服务器,所有服务器都在计算每个请求的匹配度,没有框架纯粹是我们的代码 – 2010-07-12 13:13:54