SpringBoot入门——局部与全局的异常处理

CIOAge
因为404错误是不经过controller的,所以无法通过上述办法处理。但是 SpringBoot 默认提供了一个全局的 handler 来处理所有的 HTTP 错误, 并把它映射为 /error。当发生一个 HTTP 错误, 例如 404 错误时, SpringBoot 内部的机制会将页面重定向到 /error 中。

 

SpringBoot入门——局部与全局的异常处理

 

1、构建测试代码

 

(1)、新建MAVEN项目

打开IDE—新建Maven项目—构建一个简单Maven项目

 

(2)、编写pom.xml引入包

编写pom配置引入jar包

注:引入完毕后可能项目会报红叉,更新maven即可

<project xmlns="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 { 	 } 

---------------------------------------------------------------------------------

注:关于注解类的简说请看:

https://my.oschina.net/u/3523885/blog/1489959

---------------------------------------------------------------------------------

2、将注解加到TestController类

加入@TestException注解

// 加入TestException注解 @TestException @RestController @RequestMapping("/test") public class TestController { 	 	@RequestMapping("/hello1") 	public String hello(){ 		// 自己编写的除0异常 		int a=1/0; 		 		return "hello1"; 	}  }

3、TestGlobalController类不加注解

@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:

<%@ page language="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> <meta http-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 class HttpErrorController implements ErrorController { 	 	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/-.-

显示:

责任编辑:吴金泽 来源: 开源中国社区
相关推荐

2019-01-24 16:11:19

前端全局异常数据校验

2022-03-04 08:31:07

Spring异常处理

2023-12-27 07:53:08

全局异常处理处理应用

2023-12-13 13:28:00

Spring全局异常处理架构

2019-08-29 14:30:16

代码开发工具

2009-02-06 14:11:36

ASP.NET.NET全局异常处理

2015-01-07 14:41:32

Android全局变量局部变量

2021-04-20 10:50:38

Spring Boot代码Java

2017-02-08 12:28:37

Android变量总结

2023-09-24 23:40:54

Python变量

2024-10-28 08:32:22

统一接口响应SpringBoot响应框架

2022-05-03 10:43:43

SpringJava

2018-05-14 09:15:24

Python变量函数

2024-04-16 12:18:05

编程异常处理错误返回

2020-03-16 17:20:02

异常处理Spring Boot

2022-08-03 07:07:10

Spring数据封装框架

2023-06-15 14:09:00

解析器Servlet容器

2024-02-21 12:18:00

Java虚拟机JVM

2024-08-02 10:21:32

C#Exception类自定义异常

2024-05-29 08:49:22

Python全局变量局部变量

51CTO技术栈公众号