Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 236|回复: 0

[默认分类] spring mvc 异常统一处理方式

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-11 17:15:06 | 显示全部楼层 |阅读模式

    SpringMVC提供的异常处理主要有两种方式,一种是直接实现自己的HandlerExceptionResolver,另一种是使用注解的方式实现一个专门用于处理异常的Controller——ExceptionHandler。
      
    1、实现自己的HandlerExceptionResolver,HandlerExceptionResolver是一个接口,springMVC本身已经对其有了一个自身的实现——DefaultExceptionResolver,该解析器只是对其中的一些比较典型的异常进行了拦截处理。
      

      
       
        java代码
       
       
       
      
      
       import javax.Servlet.http.HttpServletRequest;   
       import javax.servlet.http.HttpServletResponse;   
         
       import org.springframework.web.servlet.HandlerExceptionResolver;   
       import org.springframework.web.servlet.ModelAndView;   
         
       public class ExceptionHandler implements HandlerExceptionResolver {   
         
           @Override  
           public ModelAndView resolveException(HttpServletRequest request,   
                   HttpServletResponse response, Object handler, Exception ex) {   
               // TODO Auto-generated method stub   
               return new ModelAndView("exception");   
           }   
         
       }  
      

      
      上述的resolveException的第4个参数表示对哪种类型的异常进行处理,如果想同时对多种异常进行处理,可以把它换成一个异常数组。
    定义了这样一个异常处理器之后就要在applicationContext中定义这样一个bean对象,如:

      
       
        Xml代码
       
       
       
      
      
       <bean id="exceptionResolver" class="com.tiantian.xxx.web.handler.ExceptionHandler"/>  
      

      
    2、使用@ExceptionHandler进行处理
    使用@ExceptionHandler进行处理有一个不好的地方是进行异常处理的方法必须与出错的方法在同一个Controller里面
    如:

      
       
        Java代码
       
       
       
      
      
       import org.springframework.stereotype.Controller;   
       import org.springframework.web.bind.annotation.ExceptionHandler;   
       import org.springframework.web.bind.annotation.RequestMapping;   
         
       import com.tiantian.blog.web.servlet.MyException;   
         
       @Controller  
       public class GlobalController {   
         
             
           /**  
            * 用于处理异常的  
            * @return  
            */  
           @ExceptionHandler({MyException.class})   
           public String exception(MyException e) {   
               System.out.println(e.getMessage());   
               e.printStackTrace();   
               return "exception";   
           }   
             
           @RequestMapping("test")   
           public void test() {   
               throw new MyException("出错了!");   
           }   
             
             
       }  
      

      
    这里在页面上访问test方法的时候就会报错,而拥有该test方法的Controller又拥有一个处理该异常的方法,这个时候处理异常的方法就会被调用
       
    当发生异常的时候,上述两种方式都使用了的时候,第一种方式会将第二种方式覆盖
      http://gaojiewyh.iteye.com/blog/1297746
      
      
    最近使用spring mvc开发一个web系统,发现在controller里发生未捕获异常时不出日志。

    分析DispatcherServlet,初始化handlerExceptionResolvers

      
       
        Java代码
       
       
       
      
      
               /**  
            * Initialize the strategy objects that this servlet uses.  
            * <p>May be overridden in subclasses in order to initialize  
            * further strategy objects.  
            */  
           protected void initStrategies(ApplicationContext context) {   
               initMultipartResolver(context);   
               initLocaleResolver(context);   
               initThemeResolver(context);   
               initHandlerMappings(context);   
               initHandlerAdapters(context);   
       // 初始化异常处理支持器   
               initHandlerExceptionResolvers(context);   
               initRequestToViewNameTranslator(context);   
               initViewResolvers(context);   
           }   
         
       // 进入初始化处理方法,具体内容就不贴了,主要是先到上下文中搜寻我们自己定义的ExceptionResolvers,如果没有自定义的resolvers,从默认配置中读取。   
       private void initHandlerExceptionResolvers(ApplicationContext context)   
         
       // 从默认策略中取得默认配置,从DispatcherServlet.properties文件中取得相关的配置策略,但是在spring2.5的mvc jar包中properties文件中没有HandlerExceptionResolver的默认配置,返回一个EmptyList给handlerExceptionResolvers   
       protected List getDefaultStrategies(ApplicationContext context, Class strategyInterface)  
      

    1.         分析DispatcherServlet,分发处理请求
    复制代码

      
       
        Java代码
       
       
       
      
      
       // 从dispatch方法中看到,系统对请求进行具体的逻辑处理部分被catch住了一次exception,然后会使用servlet持有的ExceptionResolver进行处理   
       protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {   
               HttpServletRequest processedRequest = request;   
               HandlerExecutionChain mappedHandler = null;   
               int interceptorIndex = -1;   
         
               // Expose current LocaleResolver and request as LocaleContext.   
               LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();   
               LocaleContextHolder.setLocaleContext(buildLocaleContext(request), this.threadContextInheritable);   
         
               // Expose current RequestAttributes to current thread.   
               RequestAttributes previousRequestAttributes = RequestContextHolder.getRequestAttributes();   
               ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);   
               RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);   
         
               if (logger.isTraceEnabled()) {   
                   logger.trace("Bound request context to thread: " + request);   
               }   
                  
               try {   
                   ModelAndView mv = null;   
                   boolean errorView = false;   
         
                   try {   
                       processedRequest = checkMultipart(request);   
         
                       // Determine handler for the current request.   
                       mappedHandler = getHandler(processedRequest, false);   
                       if (mappedHandler == null || mappedHandler.getHandler() == null) {   
                           noHandlerFound(processedRequest, response);   
                           return;   
                       }   
         
                       // Apply preHandle methods of registered interceptors.   
                       HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();   
                       if (interceptors != null) {   
                           for (int i = 0; i < interceptors.length; i++) {   
                               HandlerInterceptor interceptor = interceptors;   
                               if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {   
                                   triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);   
                                   return;   
                               }   
                               interceptorIndex = i;   
                           }   
                       }   
         
                       // Actually invoke the handler.   
                       HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());   
                       mv = ha.handle(processedRequest, response, mappedHandler.getHandler());   
         
                       // Do we need view name translation?   
                       if (mv != null && !mv.hasView()) {   
                           mv.setViewName(getDefaultViewName(request));   
                       }   
         
                       // Apply postHandle methods of registered interceptors.   
                       if (interceptors != null) {   
                           for (int i = interceptors.length - 1; i >= 0; i--) {   
                               HandlerInterceptor interceptor = interceptors;   
                               interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);   
                           }   
                       }   
                   }   
                   catch (ModelAndViewDefiningException ex) {   
                       logger.debug("ModelAndViewDefiningException encountered", ex);   
                       mv = ex.getModelAndView();   
                   }   
       // 这里catch住controller抛出的异常,使用持有的ExceptionResolver处理,当没有配置自己的处理器时,程序会将异常继续往上抛出,最终交给我们的容器处理   
                   catch (Exception ex) {   
                       Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);   
                       mv = proceSSHandlerException(processedRequest, response, handler, ex);   
                       errorView = (mv != null);   
                   }   
         
                   // Did the handler return a view to render?   
                   if (mv != null && !mv.wasCleared()) {   
                       render(mv, processedRequest, response);   
                       if (errorView) {   
                           WebUtils.clearErrorRequestAttributes(request);   
                       }   
                   }   
                   else {   
                       if (logger.isDebugEnabled()) {   
                           logger.debug("Null ModelAndView returned to DispatcherServlet with name "" +   
                                   getServletName() + "": assuming HandlerAdapter completed request handling");   
                       }   
                   }   
         
                   // Trigger after-completion for successful outcome.   
                   triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);   
               }   
       // 当没有配置ExceptionResolver时,异常将到达这里,最终抛出   
               catch (Exception ex) {   
                   // Trigger after-completion for thrown exception.   
                   triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);   
                   throw ex;   
               }   
               catch (Error err) {   
                   ServletException ex = new NestedServletException("Handler processing failed", err);   
                   // Trigger after-completion for thrown exception.   
                   triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);   
                   throw ex;   
               }   
         
               finally {   
                   // Clean up any resources used by a multipart request.   
                   if (processedRequest != request) {   
                       cleanupMultipart(processedRequest);   
                   }   
         
                   // Reset thread-bound context.   
                   RequestContextHolder.setRequestAttributes(previousRequestAttributes, this.threadContextInheritable);   
                   LocaleContextHolder.setLocaleContext(previousLocaleContext, this.threadContextInheritable);   
         
                   // Clear request attributes.   
                   requestAttributes.requestCompleted();   
                   if (logger.isTraceEnabled()) {   
                       logger.trace("Cleared thread-bound request context: " + request);   
                   }   
               }   
           }  
      



    http://fancyboy2050.iteye.com/blog/1300037

      spring mvc异常设置,
      

      
       
       
         Java代码
         
         
       
       
       
             
        此段代码ZZ from http://tdcq.iteye.com/blog/890957   
        <!-- 全局异常配置 start -->     
             <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">     
                 <property name="exceptionMappings">     
                     <props>     
                         <prop key="java.lang.Exception">errors/error</prop>     
                         <prop key="java.lang.Throwable">errors/err</prop>     
                     </props>     
                 </property>     
                 <property name="statusCodes">     
                     <props>     
                         <prop key="errors/error">500</prop>     
                         <prop key="errors/404">404</prop>     
                     </props>     
                 </property>     
                 <!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->     
                 <property name="warnLogCategory" value="WARN"></property>     
                 <!-- 默认错误页面,当找不到上面mappings中指定的异常对应视图时,使用本默认配置 -->     
                 <property name="defaultErrorView" value="errors/error"></property>     
                 <!-- 默认HTTP状态码 -->     
                 <property name="defaultStatusCode" value="500"></property>     
             </bean>     
             <!-- 全局异常配置 end -->   
       
      
    1.    
    2. 用spring mvc做了个项目,但是出现异常的情况下居然没有日志输出,然后各种尝试。。。正如上面介绍的:设置日志输出级别,不定义则默认不输出警告等错误日志信息!!【当然,try catch的异常没问题】
    3. 敬请留意。
    复制代码


      http://fancyboy2050.iteye.com/blog/965663

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-20 12:12 , Processed in 0.427046 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表