一、概述:
springMVC通過HandlerExceptionResolver處理程序的異常,異常包括 Handler映射、數據綁定以及目標方法執行時發生的異常;
springMVC提供的HandlerExceptionResolver的實現類有:
- ExceptionHandler:處理異常,可以把異常寫到頁面上;
- DefaultHandlerExceptionResplver 處理指定異常;
- ResponseStatusExceptionResource 更改自定義異常的狀態碼和異常原因
- simpleMappingExceptionResolver 指定異常跳轉頁面
ExceptionHandler:
@ExceptionHandler注解:
1.在@ExceptionHandler 方法的入參中可以加入Exception 類型的參數,該參數即對應發生的異常的對象
2.在@ExceptionHandler 方法的入參不能傳入 map;若希望吧異常信息傳到頁面上,需要使用ModelAndView做返回值
3.@ExceptionHandler 存在優先級為,從小到大;越匹配優先級越高;
4.@ControllerAdvice:如果當前Handler中找不到@ExceptionHandler,則去@ControllerAdvice標記的類中查找@ExceptionHandler標記的方法來處理異常
1.目錄結構為:
2.配置:
web.xml配置:只配置了DispatcherServlet

1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 5 id="WebApp_ID" version="3.1"> 6 <servlet> 7 <servlet-name>springDispatcherServlet</servlet-name> 8 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 9 <!-- 配置DispatcherServletd 一個初始化參數:配置springmvc配置文件的位置和名稱 --> 10 <!-- 實際上也可以不通過 contextConfigLocation 來配置Springmvc的配置文件,而是用默認的 即默認的配置文件為 11 /WEB-INF/<servlet-name>-servlet.xml 本項目默認位置配置文件即為: /WEB-INF/springDispatcherServlet-servlet.xml --> 12 <init-param> 13 <param-name>contextConfigLocation</param-name> 14 <param-value>classpath:spring.xml</param-value> 15 </init-param> 16 <!-- 表示springDispatcherServlet在加載的時候被創建 --> 17 <load-on-startup>1</load-on-startup> 18 </servlet> 19 20 <!-- Map all requests to the DispatcherServlet for handling --> 21 <servlet-mapping> 22 <servlet-name>springDispatcherServlet</servlet-name> 23 <url-pattern>/</url-pattern> 24 </servlet-mapping> 25 </web-app>
spring.xmp配置:基礎配置
基礎配置包括:包掃描的配置、視圖解析器配置、<mvc:annotation-driven></mvc:annotation-driven>;

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:mvc="http://www.springframework.org/schema/mvc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="handler"></context:component-scan> 11 <!-- 配置視圖解析器 如何把handler 方法返回值解析為實際的物理視圖 --> 12 <bean 13 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 14 <property name="prefix" value="/WEB-INF/views/"></property> 15 <property name="suffix" value=".jsp"></property> 16 </bean> 17 18 <mvc:annotation-driven></mvc:annotation-driven> 19 20 </beans>
3.EceptionController.java
- 方法的入參中可以加入Exception 類型的參數,該參數即對應發生的異常的對象
- 異常信息傳到頁面上,需要使用ModelAndView做返回值
1 package handler; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.ExceptionHandler; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RequestParam; 7 import org.springframework.web.servlet.ModelAndView; 8 9 @RequestMapping("/emp") 10 @Controller 11 public class EceptionController { 12 13 @RequestMapping("/testError") 14 public String testError(@RequestParam("i") int i) { 15 System.out.println(10 / i); 16 return "success"; 17 } 18 19 @ExceptionHandler({ ArithmeticException.class }) 20 public ModelAndView handleArithmeticException(Exception ex) { 21 System.out.println("出異常了:" + ex); 22 ModelAndView md = new ModelAndView("error"); 23 md.addObject("ex", ex); 24 return md; 25 } 26 }
4.success.jsp&&error.jsp

1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html> 4 <html> 5 <head> 6 <meta charset="UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 success 11 </body> 12 </html>

1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html> 4 <html> 5 <head> 6 <meta charset="UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <h4>Error Page</h4> 11 ${ex} 12 </body> 13 </html>
5.運行結果:
當訪問:http://localhost:8080/DataOperate/emp/testError?i=10時,頁面跳轉到success頁面;當訪問http://localhost:8080/DataOperate/emp/testError?i=0時,訪問了error頁面,且error頁面打印了異常信息;
6.如果異常不匹配:
也就是說@ExceptionHandler標記的異常和實際拋出的異常不匹配,如下,比如EceptionController.java中異常時算術異常,但是@ExceptionHandler標記的只有運行時異常:那么異常存在優先級為,從小到大;越匹配優先級越高;
1 package handler; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.ExceptionHandler; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RequestParam; 7 import org.springframework.web.servlet.ModelAndView; 8 9 @RequestMapping("/emp") 10 @Controller 11 public class EceptionController { 12 13 @RequestMapping("/testError") 14 public String testError(@RequestParam("i") int i) { 15 System.out.println(10 / i); 16 return "success"; 17 } 18 19 @ExceptionHandler({ RuntimeException.class }) 20 public ModelAndView handleRuntimeException(Exception ex) { 21 System.out.println("【出異常了]:" + ex); 22 ModelAndView md = new ModelAndView("error"); 23 md.addObject("ex", ex); 24 return md; 25 } 26 }
此時,訪問;http://localhost:8080/DataOperate/emp/testError?i=0,也會跳轉到error頁面且顯示異常信息同上圖,且控制台打印:
【出異常了]:java.lang.ArithmeticException: / by zero
7.如果當前Handler中找不到@ExceptionHandler
@ControllerAdvice:如果當前Handler中找不到@ExceptionHandler,則去@ControllerAdvice標記的類中查找@ExceptionHandler標記的方法來處理異常
EceptionController.java
1 package handler; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.RequestParam; 6 7 @RequestMapping("/emp") 8 @Controller 9 public class EceptionController { 10 11 @RequestMapping("/testError") 12 public String testError(@RequestParam("i") int i) { 13 System.out.println(10 / i); 14 return "success"; 15 } 16 }
ExceptionHandlerProcess.java
1 package handler; 2 3 import org.springframework.web.bind.annotation.ControllerAdvice; 4 import org.springframework.web.bind.annotation.ExceptionHandler; 5 import org.springframework.web.servlet.ModelAndView; 6 7 @ControllerAdvice 8 public class ExceptionHandlerProcess { 9 10 @ExceptionHandler({ ArithmeticException.class }) 11 public ModelAndView handleArithmeticException(Exception ex) { 12 System.out.println("出異常了:" + ex); 13 ModelAndView md = new ModelAndView("error"); 14 md.addObject("ex", ex); 15 return md; 16 } 17 18 @ExceptionHandler({ RuntimeException.class }) 19 public ModelAndView handleRuntimeException(Exception ex) { 20 System.out.println("【出異常了]:" + ex); 21 ModelAndView md = new ModelAndView("error"); 22 md.addObject("ex", ex); 23 return md; 24 } 25 26 }
運行結果:
此時,訪問;http://localhost:8080/DataOperate/emp/testError?i=0,也會跳轉到error頁面且顯示異常信息同上圖,且控制台打印相關信息:
出異常了:java.lang.ArithmeticException: / by zero