SpringBoot入門——區域性與全域性的異常處理
1、構建測試程式碼
(1)、新建MAVEN專案
開啟IDE—新建Maven專案—構建一個簡單Maven專案
(2)、編寫pom.xml引入包
編寫pom配置引入jar包
注:引入完畢後可能專案會報紅叉,更新maven即可
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
< modelVersion>4.0.0</modelVersion>
<groupId>com.springboot</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</ artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 引入web相關包 -->
<dependency >
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Springboot devtools熱部署 依賴包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin </artifactId>
<configuration>
<!-- 如果沒有該項配置,devtools不會起作用,即應用不會restart -->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
(3)、新建一個controller類
包名:com.springboot.controller
類名:TestController
package com.springboot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//@RestController=@Controller+@ResponseBody
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/hello1")
public String hello(){
return "hello1";
}
}
(4)、新建一個Application類
包名:com.springboot
類名:TestController
package com.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
System.out.println("_____OK______");
}
}
然後執行程式
(5)、測試
輸入地址:http://localhost:8080/test/hello1
如果顯示:hello1,則測試成功
測試程式碼編寫完成
———————————————————————————————————————
2、區域性異常處理
對TestController類進行操作
(1)、創造異常點
如果設定一個變數=整數/0,則會發生ArithmeticException異常
在TestController中加入除0異常點
@RequestMapping("/hello1")
public String hello(){
// 自己編寫的除0異常
int a=1/0;
return "hello1";
}
(2)、編寫異常處理方法
在TestController中加入異常處理方法
//區域性異常處理
@ExceptionHandler(Exception.class)
public String exHandler(Exception e){
// 判斷髮生異常的型別是除0異常則做出響應
if(e instanceof ArithmeticException){
return "發生了除0異常";
}
// 未知的異常做出響應
return "發生了未知異常";
}
(3)、測試
輸入地址:http://localhost:8080/test/hello1
如果顯示:發生了除0異常,則測試成功
———————————————————————————————————————
3、全域性異常處理
(1)、建立一個新的Cpntroller類
包名:package com.springboot.controller;
類名:TestGlobalController
package com.springboot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestGlobalController {
@RequestMapping("/hello2")
public String hello2(){
// 自己編寫的異常發生點
int a=1/0;
return "hello2";
}
}
--------------------------------------------------------------------------------------
(2)、編寫全域性異常類
包名:com.springboot.controller.exception
類名:GlobalDefaultExceptionHandler
⒈全域性異常處理返回字串
package com.springboot.controller.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalDefaultExceptionHandler {
// 全域性異常處理返回字串
@ExceptionHandler(Exception.class)
@ResponseBody
public String exception(Exception e){
// 判斷髮生異常的型別是除0異常則做出響應
if(e instanceof ArithmeticException){
return "全域性:發生了除0異常";
}
// 未知的異常做出響應
return "全域性:發生了未知異常";
}
}
⒉全域性異常處理返回JSON
// 全域性異常處理返回JSON
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<String,Object> exception(Exception e){
Map<String,Object> map=new HashMap<String,Object>();
// 判斷髮生異常的型別是除0異常則做出響應
if(e instanceof ArithmeticException){
map.put("codeNumber", "1");
map.put("message", e.getMessage());
return map;
}
// 未知的異常做出響應
map.put("codeNumber", "0");
map.put("message", e.getMessage());
return map;
}
⒊全域性異常處理返回JSP
@ExceptionHandler(Exception.class)
public String exception(Exception e){
// 判斷髮生異常的型別是除0異常則做出響應
if(e instanceof ArithmeticException){
// 跳轉到test.jsp頁面
return "test";
}
// 未知的異常做出響應
// 跳轉到test.jsp頁面
return "test";
}
注:需要配置一下才能支援jsp
①需要在pom新增JSP的支援
<!-- 對JSP的解析支援 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- 對JSTL的支援 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
②需要配置application.properties
新增application.properties檔案,然後往其中寫入
# 頁面預設字首目錄
spring.mvc.view.prefix=/WEB-INF/
# 響應頁面預設字尾
spring.mvc.view.suffix=.jsp
③需要新增jsp檔案
新增JSP,放置在src/main/webapp/WEB-INF目錄下
--------------------------------------------------------------------------------------
(3)、全域性異常類應用範圍設定
⒈@ControllerAdvice簡介
在spring 3.2中,新增了@ControllerAdvice 註解可以用於定義@ExceptionHandler、@InitBinder、@ModelAttribute,並應用到所有@RequestMapping中。
這裡我們全域性異常只應用到@ExceptionHandler
⒉設定@ControllerAdvice應用範圍
設定了@ControllerAdvice應用範圍,即就設定了異常類的應用範圍
@ControllerAdvice的範圍有:
①basePackages:應用在xx包
②basePackageClasses:應用在xx類
③assignableTypes:應用在加了@Controller的類
④annotations:應用在帶有xx註解的類或者方法
————————————————————
≥簡單用法例子:
————————————————————
@ControllerAdvice(basePackages={"com.springboot.controller"})
只捕捉com.springboot.controller包中的異常
@ControllerAdvice(basePackageClasses={TestController.class})
只捕捉TestController.class中的異常
@ControllerAdvice(assignableTypes={TestController.class})
只捕捉TestController.class中的異常
@ControllerAdvice(annotations=TestException.class)
只捕捉帶有@TestException註解的類
上面四個註解一個應用包,然後的兩個用在類,而最後一個只應用於帶有XX註解的類
--------------------------------------------------------------------------------------
3.講講應用在註解怎麼寫
1、建立一個註解類
package com.springboot.annotation;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
// 這種型別的Annotations將被JVM保留,所以他們能在執行時被JVM或其他使用反射
@Retention(RUNTIME)
// 目標型別可以應用在方法
@Target(ElementType.TYPE)
// 對doc文件支援
@Documented
public @interface TestException {
}
---------------------------------------------------------------------------------
注:關於註解類的簡說請看:
---------------------------------------------------------------------------------
2、將註解加到TestController類
加入@TestException註解
// 加入TestException註解
@TestException
@RestController
@RequestMapping("/test")
public class TestController {
@RequestMapping("/hello1")
public String hello(){
// 自己編寫的除0異常
int a=1/0;
return "hello1";
}
}
3、TestController類不加註解
@RestController
@RequestMapping("/test")
public class TestGlobalController {
@RequestMapping("/hello2")
public String hello(){
// 自己編寫的除0異常
int a=1/0;
return "hello2";
}
}
4、設定異常類只捕捉帶有@TestException註解的類的異常
// 設定範圍應用於帶有@TestException的註解的類上
@ControllerAdvice(annotations={TestException.class})
public class GlobalDefaultExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public String exceptionReturnString(Exception e){
// 判斷髮生異常的型別是除0異常則做出響應
if(e instanceof ArithmeticException){
return "全域性:發生了除0異常";
}
// 未知的異常做出響應
return "全域性:發生了未知異常";
}
}
5、測試
輸入地址:http://localhost:8080/test/hello1
輸入地址:http://localhost:8080/test/hello2
(4)、處理404錯誤
因為404錯誤是不經過controller的,所以無法通過上述辦法處理。但是 SpringBoot 預設提供了一個全域性的 handler 來處理所有的 HTTP 錯誤, 並把它對映為 /error。當發生一個 HTTP 錯誤, 例如 404 錯誤時, SpringBoot 內部的機制會將頁面重定向到 /error 中。
所以我們只要實現一個 /error 對映的 Controller 即可來處理它即可
1、建立404.jsp頁面
在WEB-IFN下建立errorpages目錄,並且在此目錄下建立一個404.jsp頁面
目錄:
404.jsp:
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"><title>Test JSP</title></head><body><span>發生了404錯誤</span></html>
2、建立處理404的controller類
包名:package com.springboot.controller;
類名:HttpErrorController
package com.springboot.controller;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public classHttpErrorControllerimplementsErrorController{
private static final String ERROR_PATH = "/error";
@RequestMapping(value=ERROR_PATH)
public String handleError(){
return "errorpage/404";
}
@Override
public String getErrorPath(){
return ERROR_PATH;
}
}
3、測試
隨便輸入個地址測試引發404錯誤
例如輸入地址:http://localhost:8080/-.-
顯示: