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

前言

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

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

事实上,对代码的理解很总要,这样你就知道什么时候应该抛出什么异常了,比如数组越界,文件过大,栈越界,连接超时这些标准异常,等等。当然,在什么时候抛出什么异常不是本文的重点,网上同类的文章很多,传送门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.                   
  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.           
  21.           
  22.         <property name="maxInMemorySize"><value>1value>property>  
  23.         <property name="defaultEncoding"><value>UTF-8value>property>  
  24.         <property name="resolveLazily"><value>truevalue>property>  
  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. >  
  8. <html>  
  9. <head>  
  10. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  11. <title>error.jsptitle>  
  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.       
  21.       
  22.      
  23.       
  24.       
  25.         
  26.     <bean class="com.bestcxx.stu.fileup.exception.GlobalExceptionResolver">bean>  
  27.       
  28. 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. }  


你可能感兴趣的:(框架:spring)