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

Spring全局异常处理HandlerExceptionResolver使用

1 引言

全局异常处理在项目中经常会用到,主要作用包括统一处理异常、提供友好的错误信息、避免应用程序崩溃、记录异常日志、避免异常信息泄露等等。下文将以实现HandlerExceptionResolver接口的方式,实现全局异常处理功能及常规用法。

2 代码

下面列出几个关键文件进行介绍,源码链接在文章最后。
在这里插入图片描述

2.1 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zeroone</groupId><artifactId>zeroone</artifactId><version>1.0</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><!--  为Spring Boot项目提供一系列默认的配置和依赖管理--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.2</version><relativePath/></parent><dependencies><!--  Spring Boot核心依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Spring Boot单元测试和集成测试的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- Spring Boot构建Web应用程序的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!-- mybatis-plus核心依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.7</version></dependency><!-- 阿里数据库连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.23</version></dependency><!-- 阿里JSON解析库--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.52</version></dependency></dependencies></project>

2.2 ReturnObj.java

该类主要用于构建一个统一的返回结构和返回状态码。

package com.zeroone.entity.common;import java.util.HashMap;
import java.util.Map;/*** 统一返回结构和返回状态码*/
public class ReturnObj {/*** 正常*/public static final int SUCCESS_CODE = 200;/*** 参数异常*/public static final int BAD_REQUEST_CODE = 400;/*** 未授权*/public static final int UNAUTHORIZED_CODE = 401;/*** 系统异常*/public static final int ERROR_CODE = 500;private static final String SUCCESS_MSG = "操作成功";public static Map<String, Object> build(int code, String msg, Object data) {Map<String, Object> map = new HashMap<>();map.put("code", code);map.put("msg", msg);map.put("data", data);return map;}public static Map<String, Object> success() {return build(SUCCESS_CODE, SUCCESS_MSG, null);}public static Map<String, Object> success(Object data) {return build(SUCCESS_CODE, SUCCESS_MSG, data);}public static Map<String, Object> success(String msg, Object data) {return build(SUCCESS_CODE, msg, data);}}

2.3 UserController.java

主要用于测试

package com.zeroone.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zeroone.config.exception.MyRuntimeException;
import com.zeroone.entity.User;
import com.zeroone.entity.common.ReturnObj;
import com.zeroone.mapper.master.UserMapperMaster;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Controller
@RequestMapping("/UserController")
public class UserController {@Autowiredprivate UserMapperMaster userMapperMaster;@RequestMapping(value = "/login")@ResponseBodypublic Object login(@RequestBody User user) {if (null == user.getPhone() ) {throw new MyRuntimeException(ReturnObj.BAD_REQUEST_CODE, "手机号不能为空");}user.getName().toString();return ReturnObj.success();}
}

2.4 MyRuntimeException.java

自定义异常,主要用code和msg来区分各种异常场景,无需每种异常都建一个类。

package com.zeroone.config.exception;/*** 自定义异常*/
public class MyRuntimeException extends RuntimeException {/*** 异常码*/private int code;/*** 异常消息*/private String msg;public MyRuntimeException(int code, String msg) {super(msg);this.code = code;this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}

2.5 HandlerExceptionResolverImpl.java

全局异常处理,只需要实现HandlerExceptionResolver 接口,所有抛出的异常都会调用resolveException方法。在此方法中,根据不同的异常类型,做不同的处理,以达到灵活处理异常的目的。

package com.zeroone.config.exception;import com.alibaba.fastjson2.JSON;
import com.zeroone.entity.common.ReturnObj;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;import java.io.IOException;
import java.io.PrintWriter;/*** 全局异常处理器*/
@Component
public class HandlerExceptionResolverImpl implements HandlerExceptionResolver {public final Logger log = LoggerFactory.getLogger(getClass());@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {response.setStatus(HttpStatus.OK.value()); // 设置状态码response.setCharacterEncoding("UTF-8"); // 设置编码int code = ReturnObj.ERROR_CODE;String msg = "系统异常";// if 自定义异常// else 其他异常if (ex instanceof MyRuntimeException myEx) {code = myEx.getCode();msg = myEx.getMsg();} else {msg = ex.getMessage();}log.error("Exception is ", ex);try {PrintWriter writer = response.getWriter();writer.print(JSON.toJSONString(ReturnObj.build(code, msg, null)));writer.flush();} catch (IOException e) {log.error("Exception is ", e);}return new ModelAndView();}
}

3 测试

  • 启动项目访问:http://localhost:8080/UserController/login,参数phone为null时,触发自定义异常,可以看到返回了自定义的数据,可用于验证参数非空等场景。

在这里插入图片描述在这里插入图片描述 * 启动项目访问:http://localhost:8080/UserController/login,参数phone有值时,触发系统异常,可以看到返回了自定义的数据,可用于快速定位代码问题,或者给用户进行统一友好提示。
在这里插入图片描述在这里插入图片描述

5 源码

Gitee代码链接

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • lambda c++/java/kotlin
  • 鸿蒙(API 12 Beta6版)图形【使用Text模块实现文本显示】方舟2D图形服务
  • 【运维监控】influxdb 2.0+telegraf 监控tomcat 8.5运行情况(1)
  • 「Python」assert 断言使用方法
  • 滚雪球学MyBatis-Plus(09):乐观锁与性能优化
  • 【js逆向专题】2.浏览器调试技巧
  • 网吧业务安全对抗(有源码)
  • vant UI之van-tab如何实现标题两行显示
  • vue3 前端实现pdf打印预览 printjs
  • spring boot(学习笔记第十九课)
  • F12抓包03:设置网速(弱网测试)
  • 开放式耳机的优缺点?有什么推荐吗?四款开放式蓝牙耳机推荐
  • JavaScript网页设计案例
  • 微信小程序代码 app.json文件详细介绍
  • 前端算法面试题1--栈、队列、链表、字典与哈希表
  • Google 是如何开发 Web 框架的
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • 2017-08-04 前端日报
  • CentOS7 安装JDK
  • docker容器内的网络抓包
  • ES6 ...操作符
  • gf框架之分页模块(五) - 自定义分页
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JavaScript类型识别
  • java中具有继承关系的类及其对象初始化顺序
  • Laravel 实践之路: 数据库迁移与数据填充
  • pdf文件如何在线转换为jpg图片
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • ReactNativeweexDeviceOne对比
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • Vue官网教程学习过程中值得记录的一些事情
  • windows-nginx-https-本地配置
  • 代理模式
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 机器学习学习笔记一
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 深入浏览器事件循环的本质
  • 转载:[译] 内容加速黑科技趣谈
  • 你对linux中grep命令知道多少?
  • Java数据解析之JSON
  • 积累各种好的链接
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​ArcGIS Pro 如何批量删除字段
  • # Redis 入门到精通(一)数据类型(4)
  • #AngularJS#$sce.trustAsResourceUrl
  • $GOPATH/go.mod exists but should not goland
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)node.js知识分享网站 毕业设计 202038
  • *算法训练(leetcode)第三十九天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
  • .CSS-hover 的解释