文档章节

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

DLQ丁
 DLQ丁
发布于 2017/07/27 17:31
字数 1721
阅读 5012
收藏 292

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

显示:

 

© 著作权归作者所有

共有 人打赏支持
DLQ丁
粉丝 31
博文 14
码字总数 14639
作品 0
丰台
程序员
私信 提问
加载中

评论(23)

L
LeasonX

引用来自“清靜無虞”的评论

这个仅仅是处理controller的异常而已,压根儿不算什么全局异常处理。我不信你项目中只处理需要controller的异常,interceptor的异常你怎么处理?要想处理全局异常,需要实现HandlerExceptionResolver接口。
拦截器级别依然能处理,但是filter级别的异常处理不了,需要一个继承BasicErrorController的controller,这时候就统一异常处理能处理到了
OSC_yaxqTJ
OSC_yaxqTJ
受教
yitian_hm
yitian_hm
+1
ly6cyh
ly6cyh
:+1:
loki_lan
loki_lan
可以可以
丶snail丶
丶snail丶
我是来点赞的
DLQ丁
DLQ丁

引用来自“木瓜很瞌睡”的评论

"编写pom.xls引入包" 这个标题应该是 "编写pom.xml引入包" 吧
哈哈,这两天搞xls呢,手贱:relaxed:
木瓜很瞌睡
木瓜很瞌睡
"编写pom.xls引入包" 这个标题应该是 "编写pom.xml引入包" 吧
DLQ丁
DLQ丁

引用来自“ddatsh”的评论

<scope>true</scope> ?
哈~这个敲错了。。。
DLQ丁
DLQ丁

引用来自“清靜無虞”的评论

这个仅仅是处理controller的异常而已,压根儿不算什么全局异常处理。我不信你项目中只处理需要controller的异常,interceptor的异常你怎么处理?要想处理全局异常,需要实现HandlerExceptionResolver接口。
我这只是写了个文章而已,我还没想写基于拦截器的异常处理呢
不学无数——SpringBoot入门V

SpringBoot 1.开发一个Web程序 SpringBoot是非常适合开发Web应用的,因为他内嵌有Tomcat、Jetty、Undertow或者Netty。大部分的应用可以通过加载spring-boot-starter-web模块能够快速的创建并...

不学无数d
07/28
0
0
SpringBoot RESTful 应用中的异常处理小结

@ControllerAdvice 和 @ExceptionHandler 的区别 ExceptionHandler, 方法注解, 作用于 Controller 级别. ExceptionHandler 注解为一个 Controler 定义一个异常处理器. ControllerAdvice, 类注......

xiaogong1688
06/29
0
0
springboot(一)入门篇

今天来整理下springboot,开发工具使用eclipse(后期会再做个idea的).主要实现的功能是 1.通过数据库的查询返回前端数据. 第二步:新建entity 第三步:新建UserMapper(需要在application.propert...

zhuyuansj
2017/10/06
0
0
Spring Boot入门资料整理

Spring Boot 初识 SpringBoot前世今生 本文主要讲述spring boot的由来,即其它诞生的背景,初衷,现状,及对未来的展望。 Spring Boot参考指南中文版--Chapter1.Spring Boot中文文档 本节提供...

小致dad
2017/11/07
0
0
恒宇少年/spring-boot-chapter

简书整套文档以及源码解析 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组件 002 Spring Cloud 核心技术 对Spring Cloud核心技术全面讲解 003 Quer...

恒宇少年
04/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

AS连接网易Mumu模拟器

1、安装模拟器 打开这个网址现在模拟器然后安装 http://mumu.163.com/ 2、安装完成后启动模拟器 3、进入模拟器安装目录 例如本机的安装目录:C:\Program Files (x86)\MuMu\emulator\nemu\vmo...

HGMrWang
9分钟前
4
0
设计要做到扩展性强还挺难的

概述 在日常开发中,有时候你的上司会跟你说,这个模块的设计扩展性要高。把这句话说出来很简单,但是要做到则非常难。导致难的其中一个因素是: 你不熟悉这个行业的业务的玩法 我举个例子来...

Sam哥哥聊技术
11分钟前
0
0
聊聊 scala 的模式匹配

一. scala 模式匹配(pattern matching) pattern matching 可以说是 scala 中十分强大的一个语言特性,当然这不是 scala 独有的,但这不妨碍它成为 scala 的语言的一大利器。 scala 的 patt...

终日而思一
13分钟前
0
0
Spring事物手动回滚

手动回滚: 方法1:在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常(现在项目的做法)...

寒风中的独狼
17分钟前
0
0
直角三角形的三角函数

sinA = a/c;A = asin(a/c); 特殊角度的三角函数值

一个小妞
25分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部