当前位置: 首页 > news >正文

Spring:项目中的统一异常处理和自定义异常

介绍异常的处理方式。在项目中,都会进行自定义异常,并且都是需要配合统一结果返回进行使用。

1.背景引入

(1)背景介绍

为什么要处理异常?如果不处理项目中的异常信息,前端访问我们后端就是显示访问失败的,所以我们需要处理。但是单单处理还不够,还需要将信息返回给前端;因为异常是一类问题,所以我们可以统一进行处理,也就是统一异常处理。

(2)没有处理异常时

看一段代码:

@Slf4j
@RequestMapping("/test")
@RestController
public class TestController {@RequestMapping("/hello")public String hello() {log.info("我被前端调用了,嘤嘤嘤~");int a = 10/0;return "hello";}}

通过url进行访问:

后端日志:

所以这就是没有进行异常处理的后果

(3)简单处理异常后

下面这段代码就会对异常进行捕获,并且返回异常的具体信息

@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandler(Exception.class)public String exception(Exception e) {log.warn(e.getMessage());return e.getMessage();}
}

前端:

这样前端就知道了明确的异常信息,但是实际异常不会单独使用,都是作为一个Message封装到统一结果中进行返回。

2.异常使用方法

我们先在代码中定义一个简单的统一结果返回,用于介绍和学习异常

import lombok.Data;@Data
public class Result {private String message;private int code;public Result(String message,int code) {this.message = message;this.code = code;}public static Result fail(String message) {return new Result(message,1314);}}

(1)统一异常模版

controller:

import lombok.extern.slf4j.Slf4j;
import org.ljy.testdemo.common.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RequestMapping("/test")
@RestController
public class TestController {@RequestMapping("/hello")public String hello() {int a = 10/0;return "hello";}@RequestMapping("/heihei")public Result heihei() {return Result.fail("只因你实在是太美~");}}

异常捕获: 

import lombok.extern.slf4j.Slf4j;
import org.ljy.testdemo.common.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;@Slf4j
@ResponseBody
@RestControllerAdvice
public class ExceptionAdvice {@ExceptionHandlerpublic Result exception(Exception e) {log.error(e.getMessage(), e);return Result.fail(e.getMessage());}
}

我们通过前端就行访问:

即时后端发生了异常,前端也能收到格式化的数据,大大提高了可读性。

(2)注解解析

写法一:类@RestControllerAdvice + 方法@ExceptionHandler

表示该类下的所有方法返回的都是数据

写法二:类@ControllerAdvice + 方法@ResponseBody + 方法@ExceptionHandler

表示该方法返回数据

写法三:类@ControllerAdvice + 类@ResponseBody + 方法@ExceptionHandler

表示该类下的所有方法返回的都是数据

其他写法:可以指定捕获异常的类型,也就是在@ExceptionHandler后面加上括号,指定异常的对象

@Slf4j
@RestControllerAdvice
public class ExceptionAdvice {@ExceptionHandler(Exception.class)public Result exception(Exception e) {log.error(e.getMessage(), e);return Result.fail(e.getMessage());}
}

为什么要加上@ResponseBody注解,不加的时候默认返回视图,就会产生异常,也就是下面的效果

3.使用自定义异常

这里的自定义异常也就是定义一个异常类,然后作为@ExceptionHandler捕获的对象

(1)先自定义一个普通的异常

步骤:实现Exception类或者其子类,然后写构造方法(记得先初始化父类),可以看情况重写几个方法

于是我们得到下面的自定义异常类

public class ApplicationException extends RuntimeException{//自定义的错误结果(里面包含错误码和错误信息)protected Result errorResult;//用于throw new ApplicationException(Result.fail("我走的是构造方法"))这种情况public Result getErrorResult() {return errorResult;}/*** 构造方法  用于填充信息*/public ApplicationException(Result errorResult) {super(errorResult.getMessage());this.errorResult = errorResult;}public ApplicationException(String message) {super(message);}public ApplicationException(Throwable cause) {super(cause);}public ApplicationException(String message, Throwable cause) {super(message, cause);}
}

(2)再定义全局异常处理器

这里的全局异常处理器就是上面的统一异常处理,只需要多捕获一个自定义异常就可以了。

import lombok.extern.slf4j.Slf4j;
import org.ljy.testdemo.common.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandler(ApplicationException.class)public Result applicationExceptionHandler (ApplicationException e) {e.printStackTrace();// 打印日志if (e.getErrorResult() != null) {return e.getErrorResult();}// 一般不会为null,构造方法已经限制住了,但是保险一些if (e.getMessage() == null || e.getMessage().equals("")) {return Result.fail(e.getMessage());}// 返回具体的异常信息return Result.fail(e.getMessage());}//兜底捕获异常@ExceptionHandler(Exception.class)public Result exception(Exception e) {log.error(e.getMessage(), e);return Result.fail(e.getMessage());}
}

大致情况就这么写,接下来解析一下统一异常中的几种校验情况

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • MATLAB入门基础篇
  • 2024数学建模研赛华为杯选题建议详细思路代码文章A题B题C题D题E题F题研究生数模竞赛
  • 我的AI工具箱Tauri版-FasterWhisper音频转文本
  • 【毕业设计】基于 PHP 开发的社区交流系统
  • ubuntu 22.04 ~24.04 如何修改登录背景
  • golang学习笔记2-语法要求,注释与代码风格
  • 周边游小程序开发
  • 双击就可以打开vue项目,而不用npm run dev
  • Redis——redispluspls库通用命令以及String类型相关接口使用
  • 实用好软-----电脑端 全能音视频转换器 转换各种音视频格式
  • 打开C嘎嘎的大门:你好,C嘎嘎!(2)
  • 【Stm32】从零建立一个工程
  • C++ 把字符串转换成整数 (atoi) - 力扣(LeetCode)
  • 【GMNER】Grounded Multimodal Named Entity Recognition on Social Media
  • LeetCode题练习与总结:回文链表--234
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Android单元测试 - 几个重要问题
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • express.js的介绍及使用
  • laravel with 查询列表限制条数
  • Linux各目录及每个目录的详细介绍
  • STAR法则
  • Wamp集成环境 添加PHP的新版本
  • Webpack 4 学习01(基础配置)
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 通过几道题目学习二叉搜索树
  • 微信小程序填坑清单
  • 为什么要用IPython/Jupyter?
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • AI算硅基生命吗,为什么?
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 阿里云重庆大学大数据训练营落地分享
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • #Linux(帮助手册)
  • (39)STM32——FLASH闪存
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (补充)IDEA项目结构
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (论文阅读40-45)图像描述1
  • (一)基于IDEA的JAVA基础10
  • (原创)可支持最大高度的NestedScrollView
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)大型网站架构演变和知识体系
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • ****Linux下Mysql的安装和配置
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET Core中的时区转换问题
  • .net访问oracle数据库性能问题
  • ;号自动换行
  • @Async 异步注解使用