zoukankan      html  css  js  c++  java
  • 使用Spring MVC HandlerExceptionResolver处理异常

    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的源代码:

     

    // Check registerer HandlerExceptionResolvers...
    ModelAndView exMv = null;
    for (Iterator it = this.handlerExceptionResolvers.iterator(); exMv == null && it.hasNext();) {
    HandlerExceptionResolver resolver = (HandlerExceptionResolver) it.next();
    exMv = resolver.resolveException(request, response, handler, ex);
    }
    if (exMv != null) {
    if (logger.isDebugEnabled()) {
    logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex);
    }
    WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
    return exMv;
    }
    

      可以看到可以插入自己的HandlerExceptionResover来搞定这个问题,我们可以在resolveException方法任意处理异常和log。也可以 
    把错误信息个性化后传到view层显示。 
    我们只有简单的需求,就是把没有catch的异常记入log,将异常的完整信息放在错误页面的一个隐藏的区域,方便查找出现错误的原因。 
    首先我们实现HandlerExceptionResolver 

    package com.qunar.advertisement.exception;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.log4j.Logger;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    import org.springframework.web.servlet.ModelAndView;
    
    import com.qunar.advertisement.utils.StringPrintWriter;
    
    public class QADHandlerExceptionResolver implements HandlerExceptionResolver{
        private static Logger logger = Logger.getLogger(QADHandlerExceptionResolver.class);
        @Override
        public ModelAndView resolveException(HttpServletRequest request,
                HttpServletResponse response, Object handler, Exception ex) {
            logger.error("Catch Exception: ",ex);//把漏网的异常信息记入日志
            Map<String,Object> map = new HashMap<String,Object>();
            StringPrintWriter strintPrintWriter = new StringPrintWriter();
            ex.printStackTrace(strintPrintWriter);
            map.put("errorMsg", strintPrintWriter.getString());//将错误信息传递给view
            return new ModelAndView("error",map);
        }
    
    }
    

      我们还需要一个辅助的类StringPrintWriter,因为ex.printStackTrace参数只有个PrintWriter类型的,java自带的StringWriter 
    不可用,所以我们需要自己实现一个装饰器的StringPrintWriter。 

    package com.qunar.advertisement.utils;
    
    import java.io.PrintWriter;
    import java.io.StringWriter;
    
    public class StringPrintWriter extends PrintWriter{
    
        public StringPrintWriter(){
            super(new StringWriter());
        }
       
        public StringPrintWriter(int initialSize) {
              super(new StringWriter(initialSize));
        }
       
        public String getString() {
              flush();
              return ((StringWriter) this.out).toString();
        }
       
        @Override
        public String toString() {
            return getString();
        }
    }

    我们只需要在xml中配置一下就可以了: 

    <bean class="com.qunar.advertisement.exception.QADHandlerExceptionResolver">
    </bean>
    

      我们在错误页面隐藏区域显示错误信息: 

    <div style="display:none;">
         <c:out value="${errorMsg}"></c:out>
    </div>

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

     

     

  • 相关阅读:
    poj3067 Japan(树状数组)
    Codeforces 482C Game with Strings(dp+概率)
    LeetCode -- 推断链表中是否有环
    螺旋矩阵——正逆序
    POJ 3905 Perfect Election(2-sat)
    设计模式 之 桥接
    Codeforces Round #257 (Div. 2)
    [LeetCode][Java] Minimum Window Substring
    Unity特殊目录和脚本编译顺序
    jQuery插件 -- Cookie插件
  • 原文地址:https://www.cnblogs.com/andgoo/p/2739153.html
Copyright © 2011-2022 走看看