使用Spring MVC HandlerExceptionResolver处理异常

http://fuliang.iteye.com/blog/947191

Spring MVC的确很强大,在每一个你想的到和想不到的地方都会留下钩子,来插入自定义的实现,透明替换默认实现, 

拦截器堆栈结构设计的非常强大,多种试图的解析,url mapping的多种实现,Locale resolver、Theme resolver 
、multipart file resolver,Excepiton hanlder Resolver等等,能让Spring MVC从1.0到3.0经历巨大变化, 
仍能向后兼容,并支持很酷的RESTful风格和强大的简化xml配置的注解。 
这些功能我们在项目中经常用到,但是Excepiton hanlder Resolver可能是个生僻一点的东东,因为我们通常对错误 
的处理通常不是非常的复杂,很多情况下只是根据异常或者http error code跳转到错误页面,这个是JSP/servlet就可
以搞定,在web.xml配置一下即可。 

今天遇到一个事情,让我想用到HandlerExceptionResolver这个东东来处理异常。今天准备把自助系统进入上线状态, 
所以把log的级别从DEBUG调到INFO,结果没有catch的Runtime异常在log记录,后来跟踪了一下原来Spring把异常处理的log, 
直接使用的是debug,而不是error,所以log级别设置为INFO导致异常没有记录,看了一下spring的源代码: 
Java代码   
  1. // Check registerer HandlerExceptionResolvers...  
  2. ModelAndView exMv = null;  
  3. for (Iterator it = this.handlerExceptionResolvers.iterator(); exMv == null && it.hasNext();) {  
  4. HandlerExceptionResolver resolver = (HandlerExceptionResolver) it.next();  
  5. exMv = resolver.resolveException(request, response, handler, ex);  
  6. }  
  7. if (exMv != null) {  
  8. if (logger.isDebugEnabled()) {  
  9. logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex);  
  10. }  
  11. WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());  
  12. return exMv;  
  13. }  

可以看到可以插入自己的HandlerExceptionResover来搞定这个问题,我们可以在resolveException方法任意处理异常和log。也可以 
把错误信息个性化后传到view层显示。 
我们只有简单的需求,就是把没有catch的异常记入log,将异常的完整信息放在错误页面的一个隐藏的区域,方便查找出现错误的原因。 
首先我们实现HandlerExceptionResolver 
Java代码   
  1. package com.qunar.advertisement.exception;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. import org.apache.log4j.Logger;  
  10. import org.springframework.web.servlet.HandlerExceptionResolver;  
  11. import org.springframework.web.servlet.ModelAndView;  
  12.   
  13. import com.qunar.advertisement.utils.StringPrintWriter;  
  14.   
  15. public class QADHandlerExceptionResolver implements HandlerExceptionResolver{  
  16.     private static Logger logger = Logger.getLogger(QADHandlerExceptionResolver.class);  
  17.     @Override  
  18.     public ModelAndView resolveException(HttpServletRequest request,  
  19.             HttpServletResponse response, Object handler, Exception ex) {  
  20.         logger.error("Catch Exception: ",ex);//把漏网的异常信息记入日志  
  21.         Map<String,Object> map = new HashMap<String,Object>();  
  22.         StringPrintWriter strintPrintWriter = new StringPrintWriter();  
  23.         ex.printStackTrace(strintPrintWriter);  
  24.         map.put("errorMsg", strintPrintWriter.getString());//将错误信息传递给view  
  25.         return new ModelAndView("error",map);  
  26.     }  
  27.   
  28. }  

posted on 2012-02-24 17:48  dhj  阅读(239)  评论(0编辑  收藏  举报

导航