1. 程式人生 > >SpringBoot入門——區域性與全域性的異常處理

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/-.-

顯示: