傻瓜式学习⭐springboot 全局异常处理实例 -- @ControllerAdvice + @ExceptionHandler()⭐

springboot 全局异常处理实例 – @ControllerAdvice + @ExceptionHandler()

为什么要使用全局异常处理?

1.一方面,在编写代码时,会不经常的出现 try {} catch {} 等异常处理的代码块,当然对于小量代码来讲,在程序中添加异常处理块,没有任何的不妥。而当程序成基数的增长,一个系统里面或许或有成百上千的类,那么这个try {} catch {} 也是基数增长的,那么程序就得非常繁杂,降低了代码的可阅读行。那么可以如同通用类一般,我们将其提取出来,构建成一个层面。那么,这便是非常不错的。

2.另一方面,在大量代码的系统中,再编写新模块时,也要进行异常处理。如果我们将其集中提取出来,我们便只用关心逻辑代码如何编写,而不用因为异常导致出现错误。而且,这仅仅是新增模块,我们仔细点可以随着代码的编写去处理异常,那么,如果是修改模块呢?有的代码是要动的,有的却是要保留的,那么,这便会一不小心就会忘掉某个异常处理。说白点,异常处理就是方便后期维护和管理

本文讲解 @ControllerAdvice + @ExceptionHandler() 全局处理异常,对于程序的设计,只要设计得当,就再也不用在 MVC 架构层进行 try-catch 了!

如果操作?

在这里插入图片描述
这是一个非常干净的 Springboot 项目!开始操作,既然是全局处理异常,肯定是要编写接口以及业务层的。

先写一个简单接口!抛出异常!
在这里插入图片描述

package com.wang.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {
    @ResponseBody
    @RequestMapping("hello")
    public String hello() throws Exception {
        int a = 0;
        return a + "";
    }
}

启动,测试:
在这里插入图片描述
成功!再此,我们对接口抛出异常!再次启动测试

package com.wang.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("hello")
    public String hello() throws Exception {
        int a = 0;
        try {
            a = 1/0;
        } catch (Exception e) {
            throw new ArithmeticException("算术 Exception !");
        }
        return a + "";
    }

}

在这里插入图片描述
在这里插入图片描述
我们可以清楚的看到这边是抛出了一个异常。

我们加上 @ControllerAdvice + @ExceptionHandler() 做的全局异常处理!

package com.wang.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 GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleException() {
        return "这里是全局异常处理错误!";
    }

}

在这里插入图片描述

注意上述中,只是添加了一个异常处理程序。再次运行代码!
在这里插入图片描述
可以看出,我们的异常被异常处理程序捕获并处理!并且,还可以跳转到错误页面。

再 templates 中添加一个 error.html
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>error</title>
</head>
<body>

<h1>出现了全局异常!这里是异常页面!</h1>

</body>
</html>

页面也是十分简单,当然,跳转到 html 页面,springboot 还需要引入 thymeleaf 模板引擎!

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

对于异常处理类的更改:

package com.wang.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 GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public String handleException() {
        return "error";
    }

}

再次运行代码,这里一定要导入模板引擎,不然出现错误:
在这里插入图片描述

成功!我们在对 Service 层进行处理异常,编写代码。

Controller层:

package com.wang.controller;

import com.wang.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @Autowired
    HelloService helloService;

    @ResponseBody
    @RequestMapping("hello")
    public String hello() throws Exception {
        int a = 0;
        try {
            a = 1/0;
        } catch (Exception e) {
            throw new ArithmeticException("算术 Exception !");
        }
        return a + "";
    }

    @RequestMapping("hello1")
    @ResponseBody
    public String helloService() throws Exception {
        return helloService.HelloService(false);
    }

}

Service层:

package com.wang.service;

import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class HelloService {

    public String HelloService(boolean flag) throws Exception {
        if(flag) {
            throw new IOException();
        }
        return "这里是Service层!";
    }

}

异常处理类:

package com.wang.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public String handleException() {
        return "error";
    }

    @ExceptionHandler(IOException.class)
    @ResponseBody
    public String IOException() {
        return "这是出现了 IOException 才能出现的错误!";
    }
}

在程序中,我们可以发现,当 controller 调用 service 层时,传入参数为 fasle 时,返回正常值,当传入值时 true 时,抛出 IOException 异常!

先传入参数 false 运行程序:
在这里插入图片描述
我这里8080端口被占用,用8898端口进行访问。

可以带到运行正确。改变参数 true ,让其抛出异常进行测试。
在这里插入图片描述
在这里插入图片描述
被异常处理类进行处理。

总结

在全局异常处理中,全局异常处理类利用 aop 的思想,一旦你的Service,Controller层发生错误,便会被捕获处理,使请求返回时走异常处理类。在全局异常处理类中,可以将异常进行细化的切分,使不用的异常被不用的异常处理方法所处理,并且在最后在进行 Exception 进行异常处理,起一个兜底的作用,防止有未考虑的异常而发生意外。

这不就是个try {} catch {} 的思想所吻合吗?而这做了一个宏大的异常提取。

   try {
       ...
   } catch (IndexOutOfBoundsException e) {
       e.printStackTrace();
   } catch (IOFileUploadException e) {
       e.printStackTrace();
   } catch (ArithmeticException e) {
       e.printStackTrace();
   } ... {
       
   } catch (Exception e) {
       e.printStackTrace();
   } finally {
       ...
   }

上述便是不同异常被不同异常机制捕获处理,最后的 Exception 便起一个兜底的作用!

OK ! 全局异常机制便做了一个简单的了解。

欢迎留言!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,您想了解关于使用 @ExceptionHandler + @ControllerAdvice +枚举实现全局异常统一处理的内容,这是一个常用的方案,可以实现全局异常的捕获和处理,让程序更加健壮和稳定。 @ExceptionHandler注解用于标记一个方法,该方法用于处理指定的异常类型。@ControllerAdvice注解用于标记一个类,该类用于处理全局异常。枚举则可以用于定义异常类型,方便异常处理时的统一管理。 在实现全局异常处理时,我们可以通过 @ExceptionHandler 注解来捕获指定的异常类型,并在方法中进行相应的处理。@ControllerAdvice注解可以让我们在一个类中定义多个 @ExceptionHandler方法,用于处理不同类型的异常。同时,我们也可以使用枚举来定义不同的异常类型,方便管理和调用。 下面是一个简单的示例,演示如何使用 @ExceptionHandler + @ControllerAdvice +枚举实现全局异常统一处理: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = BusinessException.class) @ResponseBody public ResultVO handleBusinessException(BusinessException e) { return ResultVO.error(e.getCode(), e.getMessage()); } } public enum ExceptionEnum { PARAMETER_ERROR(1001, "参数错误"), DATA_NOT_FOUND(1002, "数据不存在"), SYSTEM_ERROR(5000, "系统错误"); private final int code; private final String message; ExceptionEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } } public class BusinessException extends RuntimeException { private final int code; public BusinessException(int code, String message) { super(message); this.code = code; } public BusinessException(ExceptionEnum exceptionEnum) { super(exceptionEnum.getMessage()); this.code = exceptionEnum.getCode(); } public int getCode() { return code; } } ``` 在上面的示例中,GlobalExceptionHandler类标记了@ControllerAdvice注解,用于全局异常处理。其中,handleBusinessException方法用于处理BusinessException异常,返回一个ResultVO对象,其中包含错误码和错误信息。 BusinessException则是一个自定义的异常类,它包含一个code属性和一个message属性,用于表示异常的错误码和错误信息。同时,它还提供了一个构造方法,可以根据ExceptionEnum来构造一个BusinessException对象。 ExceptionEnum则是一个枚举类,包含了不同的异常类型,每个异常类型都有一个对应的错误码和错误信息。 在实际开发中,我们可以根据实际需求来定义不同的异常类型和错误码,以便更好地管理和调用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值