SpringBoot——全局异常处理

目录

异常

项目总结

新建一个SpringBoot项目

pom.xml

Result(通用的响应结果类)

MyBusinessException自定义异常类

GlobalExceptionHandler全局异常处理类

ExceptionController控制器

SpringbootExceptionApplication启动类


参考文章:

异常

  • SpringBoot项目采用了全局异常的概念——所有方法均将异常抛出,并且专门安排一个类统一拦截并处理这些异常。
  • 对异常的处理:
    • 1、抛出异常
    • 2、使用 try...catch...finally 捕获处理异常
  • SpringBoot提供了两个注解用于拦截异常
    • 1、@ControllerAdvice:标注该类为全局异常处理类,默认拦截所有被触发的异常
    • 2、@ExceptionHandler:标注方法,用于处理特定异常
异常的分类
java.lang.Throwable(所有异常类的根类)

java.lang.Error

(错误信息)

  • 由Java虚拟机生成并抛出
  • 这类错误一般不处理
java.lang.Exception(异常信息)
StackOverFlowError:栈空间溢出错误

检查期异常

  • 在方法上固定存在的,如果调用了该方法就必须处理此异常

java.lang.RuntimeException

(运行时异常)

OutOfMemoryError:内存溢出错误java.io.IOException:I/O异常java.lang.NullPointerException:空指针异常
IllegalAccessError:非法的访问权限错误java.io.FileNotFoundException:文件找不到异常

java.lang.IndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException:数组越界异常

NoClassDefFoundError:JVM未找到类错误java.io.ClassNotFoundException:类找不到异常java.lang.IllegalArgumentException:非法参数异常
NoSuchMethodError:JVM未找到方法错误java.lang.SecurityException:安全异常java.util.ConcurrentModificationException:修改状态异常

项目总结

  • 统一异常处理通过@ControllerAdvice注解向控制器发送通知,并接收所有Controller层的通知,再结合@ExceptionHandler注解对指定的异常进行捕获处理,最后将结果返回给用户

新建一个SpringBoot项目

项目结构:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.12.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.study</groupId>
	<artifactId>springboot_exception</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot_exception</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Result(通用的响应结果类)

Result类的作用:

  1. 统一的响应格式:提高接口的一致性和可维护性。
  2. 封装错误信息:当发生异常或错误时,可以使用Result类来封装错误信息,包括错误消息和对应的状态码,便于客户端进行统一的处理和解析。
  3. 携带业务数据:除了错误信息,Result类也可以携带业务数据,例如查询结果、对象详情等,从而完整地描述接口的执行结果。
package com.study.springboot_exception.event;

import lombok.Data;

@Data
public class Result<T> {
    private String message;
    private int code;
    private T data;
}

MyBusinessException自定义异常类

package com.study.springboot_exception.exception;

import lombok.Data;

/**
 * 自定义异常类: 用于及时处理一些不符合业务逻辑的数据
 * 注意:
 * 1.必须继承RuntimeException运行时异常,并重写父类构造方法
 */
@Data
public class MyBusinessException extends RuntimeException{

    private static final long serialVersionUID=1L;
    private int code;
    private String message;

    public MyBusinessException(String message){
        super(message);
        this.message=message;
    }
    public MyBusinessException(int code,String message){
        super(message);
        this.code=code;
        this.message=message;
    }

}

GlobalExceptionHandler全局异常处理类

  • 比较常见的错误状态:
    • 200:正常响应
    • 400:错误的请求
    • 404:资源不存在
    • 500:代码无法继续执行
  • SpringBoot项目是Restful风格,大多使用@RestControllerAdvice注解
package com.study.springboot_exception.exception;

import com.study.springboot_exception.event.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.StringJoiner;

/**
 * 全局异常处理类
 */
@Slf4j
@RestControllerAdvice//标记该类为全局异常处理类
public class GlobalExceptionHandler {

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(MyBusinessException.class)//处理特定异常
    public Result handleBizException(MyBusinessException ex){
        Result<Object> result=new Result<>();
        result.setCode(ex.getCode());
        result.setMessage(ex.getMessage());
        return result;
    }

    /**
     * 参数校验不通过异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException ex){
        StringJoiner sj=new StringJoiner(";");
        ex.getBindingResult().getFieldErrors().forEach(x -> sj.add(x.getDefaultMessage()));
        Result<Object> result=new Result<>();
        result.setCode(505);
        result.setMessage(sj.toString());
        return result;
    }

    /**
     * Controller参数绑定错误
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result handleMissingServletRequestParameterException(MissingServletRequestParameterException ex){
        Result<Object> result=new Result<>();
        result.setCode(506);
        result.setMessage(ex.getMessage());
        return result;
    }

    /**
     * 其他未知异常(拦截的是全局最底层异常,兜底)
     */
    @ExceptionHandler(value=Exception.class)
    public Result handleException(Exception ex){
        Result<Object> result=new Result<>();
        result.setCode(507);
        result.setMessage("服务器内部错误");
        return result;
    }
}

ExceptionController控制器

package com.study.springboot_exception.controller;

import com.study.springboot_exception.event.Result;
import com.study.springboot_exception.exception.MyBusinessException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 处理系统中可能出现的两种异常:产品空指针异常和自定义异常
 */
@RestController
public class ExceptionController {

    /**
     * 系统内部错误
     */
    @GetMapping("/exception")
    public Result testException(){
        int i=1/0;//该语句会触发算数异常,进入全局异常处理类,所以不会执行下面的语句
        
        Result<Object> result=new Result<>();
        result.setCode(200);
        result.setMessage("success");
        result.setData("cc");
        return result;
    }
    /**
     * 自定义异常
     */
    @GetMapping("/myException")
    public Result testMyException(){
        throw new MyBusinessException(508,"自定义的异常");
    }
}

SpringbootExceptionApplication启动类

package com.study.springboot_exception;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootExceptionApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootExceptionApplication.class, args);
	}

}

 启动项目

  • 访问网址:http://localhost:8080/exception
  • int i=1/0; 会触发算术异常,在全局异常处理类中归属“其他未知异常”来进行处理

访问网址:http://localhost:8080/myException,触发自定义异常 

  • 17
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

戏拈秃笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值