zoukankan      html  css  js  c++  java
  • 使用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. }  

    我们还需要一个辅助的类StringPrintWriter,因为ex.printStackTrace参数只有个PrintWriter类型的,java自带的StringWriter 
    不可用,所以我们需要自己实现一个装饰器的StringPrintWriter。 
    Java代码  收藏代码
    1. package com.qunar.advertisement.utils;  
    2.   
    3. import java.io.PrintWriter;  
    4. import java.io.StringWriter;  
    5.   
    6. public class StringPrintWriter extends PrintWriter{  
    7.   
    8.     public StringPrintWriter(){  
    9.         super(new StringWriter());  
    10.     }  
    11.      
    12.     public StringPrintWriter(int initialSize) {  
    13.           super(new StringWriter(initialSize));  
    14.     }  
    15.      
    16.     public String getString() {  
    17.           flush();  
    18.           return ((StringWriter) this.out).toString();  
    19.     }  
    20.      
    21.     @Override  
    22.     public String toString() {  
    23.         return getString();  
    24.     }  
    25. }  

    我们只需要在xml中配置一下就可以了: 
    Xml代码  收藏代码
    1. <bean class="com.qunar.advertisement.exception.QADHandlerExceptionResolver">  
    2. </bean>  

    我们在错误页面隐藏区域显示错误信息: 
    Html代码  收藏代码
    1. <div style="display:none;">  
    2.      <c:out value="${errorMsg}"></c:out>  
    3. </div>  
  • 相关阅读:
    398. Random Pick Index
    382. Linked List Random Node
    645. Set Mismatch
    174. Dungeon Game
    264. Ugly Number II
    115. Distinct Subsequences
    372. Super Pow
    LeetCode 242 有效的字母异位词
    LeetCode 78 子集
    LeetCode 404 左叶子之和
  • 原文地址:https://www.cnblogs.com/chenying99/p/2437200.html
Copyright © 2011-2022 走看看