spring原理-5.Spring 中异常处理方法的总结

本文详细探讨了Spring中异常的处理方式,包括局部方法、拦截器和过滤器中的异常抛出,以及局部方法和全局异常捕获。通过自定义异常类和配置,展示了如何在Controller、拦截器和过滤器中捕获并处理异常,提供了代码示例和配置文件。
摘要由CSDN通过智能技术生成

前言

在编程过程中,我们总是会遇到各种各样的一样,受检异常和非受检异常,也可以对这些异常进行重写或者扩展,总而言之,这就涉及到一个处理异常的问题。

好的异常处理方式既容易配置又可以保持使用端的友好交互,更为重要的是在出现问题的时候快速的帮助我们定位问题。

事实上,对代码的理解很总要,这样你就知道什么时候应该抛出什么异常了,比如数组越界,文件过大,栈越界,连接超时这些标准异常,等等。当然,在什么时候抛出什么异常不是本文的重点,网上同类的文章很多,传送门Java 基础 积累-不断更新:异常分类:Error,Exception,RuntimeException以及其子类,其他异常

本文主要着重于异常的抛出方式和捕获方式。


再一个,对于以接口对外提供服务的项目与以页面对外提供服务的项目侧重点也是不一样的。前者需要在遇到异常时继续返回接口出参,只不过是内容有所不同,而以页面交互

的在出现异常时,则可能是跳转到了不同的页面并且给予提示信息。


最后,异常的处理包括异常的抛出和处理,抛出异常是一个,捕获异常和接下来的处理是另一个。

(1)抛出异常——捕获异常——跳转页面

(2)抛出异常——捕获异常——接口出参


代码

本文代码已经上传git:https://github.com/Bestcxy/Spring-fileup-interceptor-filter-Exception


基础工作

(1)自定义的异常类

[java]  view plain  copy
  1. package com.bestcxx.stu.fileup.exception;  
  2.   
  3. /** 
  4.  * 自定义的异常类 
  5.  * @author WuJieJecket 
  6.  * 
  7.  */  
  8. @SuppressWarnings("serial")  
  9. public class MyException extends Exception {  
  10.     public MyException(String string) {  
  11.         super(string);  
  12.     }  
  13.   
  14. }  


(2)页面等前端文件的位置-视图解析配置-关注页面基础位置WEB-INF/views

applicationContext-mvc.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
  4.     xmlns:context="http://www.springframework.org/schema/context"    
  5.     xmlns:tx="http://www.springframework.org/schema/tx"    
  6.     xmlns:aop="http://www.springframework.org/schema/aop"    
  7.     xmlns:util="http://www.springframework.org/schema/util"    
  8.     xmlns:orm="http://www.springframework.org/schema/orm"     
  9.     xmlns:mvc="http://www.springframework.org/schema/mvc"    
  10.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd    
  11.                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd    
  12.                         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd    
  13.                         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd    
  14.                         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd    
  15.                         http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd    
  16.                         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd    
  17.     ">  
  18.     <!-- 配置注解驱动 -->    
  19.     <mvc:annotation-driven/>  
  20.       
  21.     <!-- 定义默认访问 -->    
  22.     <mvc:view-controller path="/" view-name="forward:home"/>  
  23.       
  24.     <!-- 处理静态资源 -->  
  25.     <mvc:resources location="/WEB-INF/css/" mapping="/css/**" />  
  26.     <mvc:resources location="/WEB-INF/js/" mapping="/js/**" />  
  27.       
  28.     <!-- 配置视图解析器 -->  
  29.     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">    
  30.         <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>    
  31.         <property name="contentType" value="text/html"/>          
  32.         <property name="prefix" value="/WEB-INF/views/"/>    
  33.         <property name="suffix" value=".jsp"/>    
  34.     </bean>  
  35.       
  36.      
  37. </beans>  


开始了

异常的抛出

(1)局部方法抛出
[java]  view plain  copy
  1. /** 
  2.  * 异常处理测试 
  3.  * @return 
  4.  */  
  5. @GetMapping("exception")  
  6. public String exception() throws Exception{  
  7.     if(true){  
  8.         throw new MyException("报错");              
  9.     }  
  10.       
  11.     return "success";  
  12. }  


(2)拦截器抛出-类加配置文件
MyInterceptor.java
[java]  view plain  copy
  1. package com.bestcxx.stu.fileup.intercepter;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.apache.commons.fileupload.servlet.ServletFileUpload;  
  7. import org.apache.commons.fileupload.servlet.ServletRequestContext;  
  8. import org.springframework.web.servlet.HandlerInterceptor;  
  9. import org.springframework.web.servlet.ModelAndView;  
  10.   
  11. import com.bestcxx.stu.fileup.exception.MyException;  
  12.   
  13. public class MyInterceptor implements HandlerInterceptor {  
  14.     private long maxSize;  
  15.   
  16.     @Override  
  17.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)  
  18.             throws Exception {  
  19.         System.out.println(this.getClass()+" preHandle开始:"+System.currentTimeMillis());  
  20.         System.out.println(this.getClass()+" 自定义拦截器访问前:"+maxSize);  
  21.          if(request!=null && ServletFileUpload.isMultipartContent(request)) {  
  22.                 ServletRequestContext ctx = new ServletRequestContext(request);  
  23.                 long requestSize = ctx.contentLength();  
  24.                 if (requestSize > maxSize) {  
  25.                     System.out.println(this.getClass()+" preHandle结束:"+System.currentTimeMillis()+" 文件太大主动抛出异常");   
  26.                     //throw new MaxUploadSizeExceededException(maxSize);  
  27.                     throw new MyException(maxSize+"文件太大超了");  
  28.                 }  
  29.             }  
  30.         System.out.println(this.getClass()+" preHandle结束:"+System.currentTimeMillis());  
  31.         return true;  
  32.           
  33.     }  
  34.   
  35.     @Override  
  36.     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,  
  37.             ModelAndView modelAndView) throws Exception {  
  38.         // TODO Auto-generated method stub  
  39.         System.out.println(this.getClass()+" postHandle开始:"+System.currentTimeMillis());  
  40.         System.out.println(this.getClass()+" 自定义拦截器访问中:"+maxSize);  
  41.         System.out.println(this.getClass()+" postHandle结束:"+System.currentTimeMillis());  
  42.           
  43.     }  
  44.   
  45.     @Override  
  46.     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  
  47.             throws Exception {  
  48.         // TODO Auto-generated method stub  
  49.         System.out.println(this.getClass()+" afterCompletion开始:"+System.currentTimeMillis());  
  50.         System.out.println(this.getClass()+" 自定义拦截器访问后:"+maxSize);  
  51.         System.out.println(this.getClass()+" afterCompletion结束:"+System.currentTimeMillis());  
  52.   
  53.     }  
  54.   
  55.     public void setMaxSize(long maxSize) {  
  56.         this.maxSize = maxSize;  
  57.     }  
  58.       
  59.       
  60.   
  61. }  

applicationContext-intercepter.xml
[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
  4.     xmlns:context="http://www.springframework.org/schema/context"    
  5.     xmlns:tx="http://www.springframework.org/schema/tx"    
  6.     xmlns:aop="http://www.springframework.org/schema/aop"    
  7.     xmlns:util="http://www.springframework.org/schema/util"    
  8.     xmlns:orm="http://www.springframework.org/schema/orm"     
  9.     xmlns:mvc="http://www.springframework.org/schema/mvc"    
  10.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd    
  11.                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd    
  12.                         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd    
  13.                         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd    
  14.                         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd    
  15.                         http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd    
  16.                         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd    
  17.     ">  
  18.     <!-- 拦截器配置 -->  
  19.      <mvc:interceptors>  
  20.         <mvc:interceptor>  
  21.             <mvc:mapping path="/**"/>  
  22.             <bean class="com.bestcxx.stu.fileup.intercepter.MyInterceptor">  
  23.                 <!-- <property name="maxSize" value="5242880"></property> --><!-- 5mb -->  
  24.                 <property name="maxSize" value="5000"></property>  
  25.             </bean>  
  26.         </mvc:interceptor>  
  27.      </mvc:interceptors>  
  28.       
  29. </beans>  

(3)过滤器抛出-类加web.xml

(4)Spring 为文件上传大小限制单独提供的异常-MaxUploadSizeExceededException
需要增加配置文件
applicationContext-file.xml
[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
  4.     xmlns:context="http://www.springframework.org/schema/context"    
  5.     xmlns:tx="http://www.springframework.org/schema/tx"    
  6.     xmlns:aop="http://www.springframework.org/schema/aop"    
  7.     xmlns:util="http://www.springframework.org/schema/util"    
  8.     xmlns:orm="http://www.springframework.org/schema/orm"     
  9.     xmlns:mvc="http://www.springframework.org/schema/mvc"    
  10.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd    
  11.                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd    
  12.                         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd    
  13.                         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd    
  14.                         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd    
  15.                         http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd    
  16.                         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd    
  17.     ">  
  18.     <!--文件上传-->  
  19.     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
  20.         <!-- <property name="maxUploadSize"><value>1</value></property> -->  
  21.         <!-- <property name="maxUploadSize"><value>5242880</value></property> --><!-- 设置上传文件的最大尺寸为 5mb=5*1024kb=5*1024*1024b -->  
  22.         <property name="maxInMemorySize"><value>1</value></property><!-- 小于该尺寸的文件不生成临时文件 -->  
  23.         <property name="defaultEncoding"><value>UTF-8</value></property><!-- 默认上传格式为utf-8 -->  
  24.         <property name="resolveLazily"><value>true</value></property><!-- 延迟处理异常-将异常交予 controller 处理 -->  
  25.     </bean>   
  26. </beans>  


异常的捕获

(1)局部方法捕获-与抛出异常的方法处于同一个controller类-可接口可页面
这里是捕获异常后跳转到一个页面
[java]  view plain  copy
  1. /** 
  2.      * 捕获本类的异常 
  3.      * 优先级比全局异常高 
  4.      * 针对页面请求的异常处理,默认返回error.jsp 
  5.      * 一个类仅允许存在一个 @ExceptionHandler 标注的方法 
  6.      * @param ex 
  7.      * @param request 
  8.      * @return 
  9.      */  
  10.     @ExceptionHandler(Exception.class)  
  11.     public ModelAndView handlePageException(Exception ex, WebRequest request) {  
  12.     request.setAttribute("msg","异常捕获:"+this.getClass()+" "+ex.getMessage(), RequestAttributes.SCOPE_REQUEST);  
  13.     ModelAndView mav = new ModelAndView("error");  
  14.     mav.addObject("ex", ex);  
  15.     return mav;  
  16.     }  
  17.       
  18.       
  19.       
  20.    
  21.   
  22.     /** 
  23.      * 异常处理测试 
  24.      * @return 
  25.      */  
  26.     @GetMapping("exception")  
  27.     public String exception() throws Exception{  
  28.         if(true){  
  29.             throw new MyException("报错");              
  30.         }  
  31.           
  32.         return "success";  
  33.     }  



WEB-INF/error.jsp
[html]  view plain  copy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. %>  
  7. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  8. <html>  
  9. <head>  
  10. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  11. <title>error.jsp</title>  
  12. </head>  
  13. <body>  
  14.     <h1> ${msg} </h1>  
  15.     <h1> ${ex} </h1>  
  16. </body>  
  17. </html>  


如果是返回一个接口的话
需要注意的是,一个类只能有一个方法被 @Exceptionhandler 注释
本文使用@ResponseBody 做实体与json转化。其他更便捷方法请参考 Spring json和对象的自动转化

[java]  view plain  copy
  1. /** 
  2.      * 捕获本类的异常 
  3.      * 优先级比全局异常高 
  4.      * 针对接口调动的异常处理 
  5.      * 一个类仅允许存在一个 @ExceptionHandler 标注的方法 
  6.      * @param ex 
  7.      * @param request 
  8.      * @return 
  9.      */  
  10.     @ExceptionHandler(Exception.class)  
  11.     @ResponseBody  
  12.     public Object handleRestfulException(Exception ex, WebRequest request) {  
  13.         request.setAttribute("msg","异常捕获:"+this.getClass()+" "+ex.getMessage(), RequestAttributes.SCOPE_REQUEST);  
  14.         ModelAndView mav = new ModelAndView("error");  
  15.         mav.addObject("ex", ex);  
  16.         HashMap map=new HashMap();  
  17.         map.put("msg""非 ModelAndView 的实体或者字符串");  
  18.         return map;  
  19.     }  


(2)全局捕获

有三种方式,以为只需要一种就可以了,所以将他们同意罗列出来
applicationContext-exception.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
  4.     xmlns:context="http://www.springframework.org/schema/context"    
  5.     xmlns:tx="http://www.springframework.org/schema/tx"    
  6.     xmlns:aop="http://www.springframework.org/schema/aop"    
  7.     xmlns:util="http://www.springframework.org/schema/util"    
  8.     xmlns:orm="http://www.springframework.org/schema/orm"     
  9.     xmlns:mvc="http://www.springframework.org/schema/mvc"    
  10.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd    
  11.                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd    
  12.                         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd    
  13.                         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd    
  14.                         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd    
  15.                         http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd    
  16.                         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd    
  17.     ">  
  18.    <!-- 方式一 -->  
  19.    <!-- 全局异常捕获-针对页面访问 -->  
  20.     <!-- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  21.          定义默认的异常处理页面  
  22.         <property name="defaultErrorView" value="error"/>  
  23.         定义异常处理页面用来获取异常信息的变量名,也可不定义,默认名为exception   
  24.         <property name="exceptionAttribute" value="ex"/>  
  25.         设置日志输出级别,不定义则默认不输出警告等错误日志信息       
  26.         <property name="warnLogCategory" value="WARN"></property>   
  27.         默认HTTP状态码       
  28.         <property name="defaultStatusCode" value="200"></property>       
  29.            
  30.         对于需要特殊处理的异常  
  31.         <property name="exceptionMappings">       
  32.              <props>       
  33.                  <prop key="java.lang.Exception">error</prop>       
  34.                  <prop key="java.lang.Error">error</prop>  
  35.              </props>       
  36.          </property>       
  37.          <property name="statusCodes">       
  38.              <props>       
  39.                  <prop key="error">500</prop>/views/error.jsp  
  40.              </props>       
  41.          </property>  
  42.     </bean> -->  
  43.       
  44.     <!-- 方式二 -->  
  45.     <!-- Exception 类捕获-针对页面或者接口访问-->  
  46.    <!-- <context:component-scan base-package="com.bestcxx.stu.fileup.exception.ExceptionResolver"/>  -->  
  47.       
  48.     <!-- 方式三 -针对页面或者接口访问-->  
  49.     <!-- 全局异常处理器只要你实现了HandlerExceptionResolver接口,这个类就是一个全局异常处理器-->    
  50.     <bean class="com.bestcxx.stu.fileup.exception.GlobalExceptionResolver"></bean>  
  51.       
  52. </beans>  

方式一是针对页面访问的
方式二和方式三可以是页面也可以是接口(本例是页面处理,返回类型修改为 ModelAndView 类型就可以了),且方式二和方式三需要单独提供处理类

方式二ExceptionResolver.java
[java]  view plain  copy
  1. package com.bestcxx.stu.fileup.exception;  
  2.   
  3. import org.springframework.web.bind.annotation.ControllerAdvice;  
  4. import org.springframework.web.bind.annotation.ExceptionHandler;  
  5. import org.springframework.web.multipart.MaxUploadSizeExceededException;  
  6. import org.springframework.web.servlet.ModelAndView;  
  7.   
  8. /** 
  9.  * 全局异常配置 
  10.  * @author Administrator 
  11.  * 
  12.  */  
  13. @ControllerAdvice  
  14. public class ExceptionResolver {  
  15.       
  16.     @ExceptionHandler(RuntimeException.class)  
  17.     public ModelAndView handlerRuntimeException(RuntimeException ex){  
  18.         if(ex instanceof MaxUploadSizeExceededException){  
  19.             return new ModelAndView("error").addObject("msg""文件太大!");           
  20.         }  
  21.         return new ModelAndView("error").addObject("msg""未知错误:"+ex);    
  22.     }  
  23.       
  24.     @ExceptionHandler(Exception.class)  
  25.     public ModelAndView handlerMaxUploadSizeExceededException(Exception ex){  
  26.         if(ex instanceof Exception){  
  27.             return new ModelAndView("error").addObject("msg", ex);            
  28.         }  
  29.           
  30.         return new ModelAndView("error").addObject("msg""未知错误:"+ex);    
  31.           
  32.     }  
  33.   
  34. }  

方式三GlobalExceptionResolver.java

[java]  view plain  copy
  1. package com.bestcxx.stu.fileup.exception;  
  2.   
  3. import javax.servlet.http.HttpServletRequest;  
  4. import javax.servlet.http.HttpServletResponse;  
  5.   
  6. import org.springframework.web.multipart.MaxUploadSizeExceededException;  
  7. import org.springframework.web.servlet.HandlerExceptionResolver;  
  8. import org.springframework.web.servlet.ModelAndView;  
  9.   
  10. public class GlobalExceptionResolver implements HandlerExceptionResolver {  
  11.   
  12.     @Override  
  13.     public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,  
  14.             Exception ex) {  
  15.         ModelAndView modelAndView=new ModelAndView();    
  16.          System.out.println("异常信息输出:"+ex.toString());  
  17.         //如果是文件太大  
  18.         if (ex instanceof MaxUploadSizeExceededException) {  
  19.             long maxSize = ((MaxUploadSizeExceededException) ex).getMaxUploadSize();  
  20.             System.out.println(this.getClass()+" 上传文件太大,不能超过" + maxSize/1024/1024 + "mb"); // 打印错误信息  
  21.               
  22.             //将错误信息传到页面    
  23.             modelAndView.addObject("msg",this.getClass()+" 出现异常:"+"上传文件太大,不能超过" + maxSize/1024/1024 + "mb"+ex.getMessage());   
  24.               
  25.             //指向到错误界面    
  26.             modelAndView.setViewName("error");    
  27.             return modelAndView;  
  28.         }   
  29.           
  30.           
  31.         if(ex instanceof MyException){ //自定义异常  
  32.              modelAndView.addObject("msg","自定义异常:"+ex.getMessage());    
  33.         }else{    
  34.             //如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)。    
  35.             modelAndView.addObject("msg","未知异常:"+ex.getMessage());    
  36.         }    
  37.           
  38.         //将错误信息传到页面    
  39.         modelAndView.addObject("msg","出现异常:"+ex.getMessage());    
  40.             
  41.         //指向到错误界面    
  42.         modelAndView.setViewName("error");    
  43.             
  44.         return modelAndView;  
  45.     }  
  46.   
  47. }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值