【SpringBoot】6 全局异常捕获

news2024/11/20 11:37:22

介绍

在项目开发中,如果每个 Controller 都增加 try catch 方法去捕获异常及处理,就会导致代码变得很繁琐、效率低下,而大部分异常是不能直接向外抛出,需要有个统一的显示处理方法,因此需要加上全局异常捕获统一获取并进行异常处理,而不会因为一个异常的抛出导致程序的报错或者崩溃。
通常会将各种类型的异常处理过程进行解耦,保证业务逻辑单一,相关异常处理单一。对异常信息的返回进行封装,保证错误信息对用户的友好性,避免将异常、错误直接抛出给用户。

对比

对比未添加全局异常捕获和添加全局异常捕获后的区别。
添加一个 Post 方法,用浏览器去访问。

UserController.java

package com.lm.system.controller;

import com.lm.system.common.ResultBody;
import com.lm.system.common.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;


/**
 * @Author: DuHaoLin
 * @Date: 2024/7/26
 */
@Slf4j
@RestController
@Api(tags = "用户接口")
public class UserController {

    @GetMapping("user")
    @ApiOperation("获取用户信息")
    public String user() {
        User user = User.builder()
                        .name("Tom")
                        .age(18)
                        .gender(0)
                        .build();
        return ResultBody
                .build(HttpStatus.OK)
                .setData(user)
                .setCount(1)
                .getReturn();
    }

    @GetMapping("addUser")
    @ApiOperation("添加用户信息")
    public String addUser(@RequestBody User user) {
        log.info("user: {}", user);
        return ResultBody
                .build(HttpStatus.OK)
                .getReturn();
    }

}

添加全局异常捕获前

在这里插入图片描述

添加全局异常捕获后

在这里插入图片描述
添加全局异常捕获前,返回的错误信息看着很乱,错误原因看起来不够清晰;添加全局异常捕获后,返回的错误信息很清晰,简单易懂,便于前端开发及用户查看。

代码实现

在 system 目录下,新建一个 handler 目录,在 handler 目录下,新建一个 GlobalExceptionHandler 类。

GlobalExceptionHandler.java

package com.lm.system.handler;

import com.lm.system.common.ResultBody;
import com.lm.system.exception.DataBaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author: DuHaoLin
 * @Date: 2024/7/27
 */
@Slf4j
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {

    public GlobalExceptionHandler() {}

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public String handleHttpMessageNotReadableException(Exception e, HttpServletRequest request) {
        log.error("400-参数解析失败,{},{}", e.getMessage(), request.getServletPath());
        e.printStackTrace();
        return ResultBody
                .build(HttpStatus.BAD_REQUEST)
                .setMsg("参数解析失败")
                .getReturn();
    }

    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public String handleHttpRequestMethodNotSupportedException(Exception e, HttpServletRequest request) {
        log.error("405-不支持当前请求方法,{},{}", e.getMessage(), request.getServletPath());
        e.printStackTrace();
        return ResultBody
                .build(HttpStatus.METHOD_NOT_ALLOWED)
                .setMsg("不支持当前请求方法")
                .getReturn();
    }

    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public String handleHttpMediaTypeNotSupportedException(Exception e, HttpServletRequest request) {
        log.error("415-不支持当前媒体类型,{},{}", e.getMessage(), request.getServletPath());
        e.printStackTrace();
        return ResultBody
                .build(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
                .setMsg("不支持当前媒体类型")
                .getReturn();
    }

    @ExceptionHandler({DataBaseException.class})
    public String handleDataBaseException(Exception e, HttpServletRequest request) {
        log.error("500-数据库操作失败,{},{}", e.getMessage(), request.getServletPath());
        e.printStackTrace();
        return ResultBody
                .build(HttpStatus.INTERNAL_SERVER_ERROR)
                .setMsg("数据库操作失败")
                .getReturn();
    }

    @ExceptionHandler({Exception.class})
    public String handleException(Exception e, HttpServletRequest request) {
        log.error("500-系统内部错误,{},{}", e.getMessage(), request.getServletPath());
        e.printStackTrace();
        return ResultBody
                .build(HttpStatus.INTERNAL_SERVER_ERROR)
                .setMsg("系统内部错误")
                .getReturn();
    }

}


项目目录结构

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1954828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习中常用损失函数介绍

选择正确的损失函数对于训练机器学习模型非常重要。不同的损失函数适用于不同类型的问题。本文将总结一些常见的损失函数,并附有易于理解的解释、用法和示例 均方误差损失(MSE) loss_fn nn.MSELoss()py均方误差(Mean Squared Error,简称 MSE…

Navidrome音乐服务器 + 音流APP = 释放你的手机空间

20240727 By wdhuag 目录 前言: 参考: Navidrome音乐服务器 Demo试用: 支持多平台: 下载: 修改配置: 设置用NSSM成服务启动: 服务器本地访问网址: 音流 歌词封面API&am…

Golang | Leetcode Golang题解之第292题Nim游戏

题目: 题解: func canWinNim(n int) bool {return n%4 ! 0 }

网站打包封装成app,提高用户体验和商业价值

网站打包封装成app的优势 随着移动互联网的普及,用户对移动应用的需求越来越高。网站打包封装成app可以满足用户的需求,提高用户体验和商业价值。 我的朋友是一名电商平台的运营负责人,他曾经告诉我,他们的网站流量主要来自移动…

vite + xlsx + xlsx-style 导出 Excel

如下 npm i 依赖 npm i xlsxnpm i xlsx-style-vite1、简单的使用:.vue文件中使用 const dataSource ref([]) // 数据源const columns [{title: 用户名,key: userName,width: 120,},{title: 用户组,key: userGroup,width: 120,},{title: 状态,key: enable,width: …

MySQL 视图与事务

文章目录 视图事务事物的四大特性(ACID)事务的开启和结束事物隔离级别现象脏读不可重复度幻读 隔离级别读未提交(READ UNCOMMITTED)读提交 (READ COMMITTED)可重复读 (REPECTABLE READ)串行化 (SERIALIZABLE) 查看与设置事务隔离级别重复读的…

【前端 13】Vue快速入门

Vue快速入门 在现代Web开发中,尽管通过HTML、CSS和JavaScript我们能够构建出美观且功能丰富的页面,但随着项目规模的增大,这种传统的开发方式在效率上逐渐显得力不从心。为了提高开发效率,前端开发者们引入了多种框架和库&#x…

Python酷库之旅-第三方库Pandas(050)

目录 一、用法精讲 181、pandas.Series.var方法 181-1、语法 181-2、参数 181-3、功能 181-4、返回值 181-5、说明 181-6、用法 181-6-1、数据准备 181-6-2、代码示例 181-6-3、结果输出 182、pandas.Series.kurtosis方法 182-1、语法 182-2、参数 182-3、功能 …

异步通信方式的两种消息传输模型

文章目录 一、点对点模型1.1 什么是点对点模型1.2 点对点模型的特点 二、发布订阅模型2.1 什么是发布订阅模型2.2 发布订阅模式的日常案例2.3 发布订阅模型的特点 三、总结参考资料 一、点对点模型 1.1 什么是点对点模型 点对点模型(也叫队列模型) 1.2…

Shiro安全框架与SpringBoot的整合(下)

目录 一、整合前的配置 1.1 导入shiro依赖 1.2 config配置 1.2.1 ShiroConfig(⭐) 1.2.2 MyConfig(拦截器配置) 3. 拦截器(LoginInterceptor) 二、认证登录 2.1. controller 2.2 service和serviceImpl(不用) 2.3 mapper …

[Meachines] [Easy] Blocky Jar包反编译

信息收集 IP AddressOpening Ports10.10.10.37TCP:21,22,80,25565 $ nmap -p- 10.10.10.37 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 21/tcp open ftp ProFTPD 1.3.5a 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu …

自动驾驶的六个级别是什么?

自动驾驶汽车和先进的驾驶辅助系统(ADAS)预计将帮助拯救全球数百万人的生命,消除拥堵,减少排放,并使我们能够在人而不是汽车周围重建城市。 自动驾驶的世界并不只由一个维度组成。从没有任何自动化到完整的自主体验&a…

VScode调试Python代码

用Python debugger 参考 vscode-python的debug 教学(最全)

动手学深度学习55 循环神经网络 RNN 的实现

动手学深度学习55 循环神经网络 RNN 的实现 从零开始实现简洁实现QA 课件:https://zh-v2.d2l.ai/chapter_recurrent-neural-networks/rnn-scratch.html 从零开始实现 %matplotlib inline import math import torch from torch import nn from torch.nn import fun…

【前端逆向】最佳JS反编译利器,原来就是chrome!

有时候需要反编译别人的 min.js。 比如简单改库、看看别人的 min,js 干了什么,有没有重复加载?此时就需要去反编译Javascript。 Vscode 里面有一些反编译插件,某某Beautify等等。但这些插件看人品,运气不好搞的话,反…

力扣高频SQL 50题(基础版)第二十题

文章目录 力扣高频SQL 50题(基础版)第二十题2356.每位教师所教授的科目种类的数量题目说明思路分析实现过程准备数据实现方式结果截图 力扣高频SQL 50题(基础版)第二十题 2356.每位教师所教授的科目种类的数量 题目说明 表: Te…

算法——二分查找(day10)

目录 69. x 的平方根 题目解析: 算法解析: 代码: 35. 搜索插入位置 题目解析: 算法解析: 代码: 69. x 的平方根 69. x 的平方根 - 力扣(LeetCode) 题目解析: 老…

2025第十九届中国欧亚国际军民两用技术及西安国防电子航空航天暨无人机展

2025第十九届中国欧亚国际军民两用技术及西安国防电子航空航天暨无人机展 时间:2025年3月14-16日 地点:西安国际会展中心 详询主办方陆先生 I38(前三位) I82I(中间四位) 9I72(后面四位&am…

中间层 k8s(Kubernetes) 到底是什么,架构是怎么样的?

你是一个程序员,你用代码写了一个博客应用服务,并将它部署在了云平台上。 但应用服务太过受欢迎,访问量太大,经常会挂。 所以你用了一些工具自动重启挂掉的应用服务,并且将应用服务部署在了好几个服务器上,…

【C++】实验六

题目: 1、苹果和虫子 描述:你买了一箱n个苹果,很不幸的是买完时箱子里混进了一条虫子。虫子每x小时能吃掉一个苹果,假设虫子在吃完一个苹果之前不会吃另一个,那么经过y小时你还有多少个完整的苹果? 输入…