springboot全局异常处理示例

server/2025/1/22 18:32:40/

这种错误交给前端无法处理。

  • 需要自定义一些错误响应类给前端
package cn.yam.bloomfilter.exception;import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<Map<String, Object>> handleAllExceptions(Exception ex) {Map<String, Object> response = new HashMap<>();response.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());response.put("message", "服务器内部错误");return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);}
}
  1. 创建一个全局异常处理类。
  2. 使用 @ControllerAdvice@ExceptionHandler 注解。|
  3. 定义返回 JSON 格式的错误响应

处理完成之后,就变成如下图所示。

如何自定义发现的异常

以请求参数错误为例子:

  • 定义一个 异常类InvalidParameterException
package cn.yam.bloomfilter.exception;public class InvalidParameterException extends RuntimeException {public InvalidParameterException(String message) {super(message);}
}
  • 抛出
@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public ResponseEntity<User> getUserById(@PathVariable Long id) {User user = userService.getUserById(id);if (user == null) {throw new InvalidParameterException("用户ID: " + id);}return ResponseEntity.ok(user);}
}
  • 全局异常异常处理器
package cn.yam.bloomfilter.exception;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(InvalidParameterException.class)public ResponseEntity<Map<String, Object>> handleInvalidParameterException(InvalidParameterException ex) {Map<String, Object> response = new HashMap<>();response.put("status", HttpStatus.BAD_REQUEST.value());response.put("message", "参数错误: " + ex.getMessage());return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);}}

探究 ResponseEntity作用


场景描述

假设我们有一个 /resource/{id} 接口,用于根据 ID 查找资源。如果资源不存在,返回 404 Not Found 和错误信息;如果资源存在,返回 200 OK 和资源数据。


  1. 不加 ResponseEntity 的例子
package cn.yam.bloomfilter.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
public class ResourceController {@GetMapping("/resource/{id}")public Map<String, Object> getResource(@PathVariable int id) {Map<String, Object> response = new HashMap<>();// 模拟资源查找if (id == 1) {response.put("data", "Resource Data");} else {response.put("status", 404);response.put("message", "资源未找到");}return response;}
}

测试结果

  • 请求 /resource/1:
    • 响应体:
{"data": "Resource Data"
}
- 状态码: `200 OK`(默认状态码)
  • 请求 /resource/2:
    • 响应体:
{"status": 404,"message": "资源未找到"
}
- 状态码: `200 OK`(默认状态码)

问题

  • 即使资源未找到,状态码仍然是 200 OK,这不符合 RESTful API 的设计规范。
  • 客户端无法通过状态码快速判断请求是否成功。

  1. ResponseEntity 的例子
package cn.yam.bloomfilter.controller;import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@RestController
public class ResourceController {@GetMapping("/resource/{id}")public ResponseEntity<Map<String, Object>> getResource(@PathVariable int id) {Map<String, Object> response = new HashMap<>();// 模拟资源查找if (id == 1) {response.put("data", "Resource Data");return new ResponseEntity<>(response, HttpStatus.OK);} else {response.put("status", 404);response.put("message", "资源未找到");return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);}}
}

测试结果

  • 请求 /resource/1:
    • 响应体:
{"data": "Resource Data"
}
- 状态码: `200 OK`
  • 请求 /resource/2:
    • 响应体:
{"status": 404,"message": "资源未找到"
}
- 状态码: `404 Not Found`

优点

  • 状态码和响应体都符合 RESTful API 的设计规范。
  • 客户端可以通过状态码快速判断请求是否成功。

  1. 对比总结
特性**不加 **ResponseEntity**加 **ResponseEntity
状态码控制无法动态设置状态码,默认返回 200 OK可以动态设置状态码(如 200 OK404 Not Found)。
响应体可以返回自定义 JSON 数据。可以返回自定义 JSON 数据。
是否符合 RESTful 规范不符合,状态码无法反映实际错误。符合,状态码和响应体都能正确反映请求结果。
客户端处理客户端需要解析响应体才能判断是否出错。客户端可以通过状态码快速判断是否出错。

常见异常总结:

  1. 参数错误
// 访问的是http://localhost:8080/api/users/id
// id 默认是1-5 ,测试访问http://localhost:8080/api/users/999
  • 定义InvalidParameterException 异常类
package cn.yam.bloomfilter.exception;public class InvalidParameterException extends RuntimeException {public InvalidParameterException(String message) {super(message);}
}
  • 在控制层抛出InvalidParameterException
@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public ResponseEntity<User> getUserById(@PathVariable Long id) {User user = userService.getUserById(id);if (user == null) {throw new InvalidParameterException("用户ID: " + id);}return ResponseEntity.ok(user);}
}
  • 在全局异常拦截类中拦截
package cn.yam.bloomfilter.exception;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public Object handleAllExceptions(Exception ex) {Map<String, Object> response = new HashMap<>();response.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());response.put("message", ex.getMessage());return response;}@ExceptionHandler(InvalidParameterException.class)public ResponseEntity<Map<String, Object>> handleInvalidParameterException(InvalidParameterException ex) {Map<String, Object> response = new HashMap<>();response.put("status", HttpStatus.BAD_REQUEST.value());response.put("message", "参数错误: " + ex.getMessage());return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);}}

  1. 路径匹配错误
// 访问的是http://localhost:8080/ap##??djjd
  • 补充 yml 配置
spring:mvc:throw-exception-if-no-handler-found: trueweb:resources:add-mappings: false

  1. 用来兜底处理所有未被特定异常处理器捕获的异常。
package cn.yam.bloomfilter.exception;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public Object handleAllExceptions(Exception ex) {Map<String, Object> response = new HashMap<>();response.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());response.put("message", ex.getMessage());return response;}
}

http://www.ppmy.cn/server/160534.html

相关文章

医院管理系统小程序设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

数据结构——双向链表(带头、循环)

1、双链表 双链表也是链表的一种&#xff0c;双链表的每个数据节点中都有两个指针&#xff0c;分别指向前驱节点和后继结点 数据节点如下图所示&#xff1a; 2、双向带头循环链表 带头双向循环链表是链表中带头&#xff08;哨兵位&#xff09;、双向、循环三种属性的结合体 …

RavenMarket:用AI和区块链重塑预测市场

不论是美股市场还是加密市场&#xff0c;AI都是本轮周期里的最大叙事。本轮AI的最大受益者英伟达市值超越苹果一跃成为全球第一大公司&#xff0c;加密领域围绕着AI的创新也是层出不穷&#xff0c;很多项目方开始向着AI转型。 而近期币圈最热门的板块就是AI agent&#xff0c;…

研究机构科研管控系统(源码+文档+部署+讲解)

引言 在科研机构中&#xff0c;科研项目的管控是确保研究质量和效率的关键。科研管控系统作为一个创新的数字化解决方案&#xff0c;通过智能化管理和服务&#xff0c;提升了科研项目管理的透明度和效率。 系统概述 科研管控系统采用前后端分离的架构设计&#xff0c;服务端…

React+Cesium基础教程(001):创建基于React的Cesium项目及对Cesium进行基本配置

文章目录 01-基于react的cesium项目创建基于React的Cesium项目Cesium基本配置设置默认启动视角完整项目下载地址01-基于react的cesium项目 创建基于React的Cesium项目 创建react项目: create-react-app react-cesium-basic安装[cesium1.93.0]版本: npm install cesium@1.…

LLaMA Factory框架微调GLM-4大模型

摘要&#xff1a;本论文详细阐述了在 Ubuntu 24.04 系统环境下&#xff0c;利用 LLaMA Factory 框架对 GLM - 4 - 9B - Chat 模型进行微调的全过程及其成果。首先介绍了实验环境的配置&#xff0c;包括 A10 显卡、nvidia 驱动版本 550、python 3.12 环境以及 CUDA 12.0 版本&am…

【gopher的java学习笔记】Java中Mapper与Entity的关系详解

在Java后端开发中&#xff0c;特别是在使用MyBatis等持久层框架时&#xff0c;Mapper与Entity的关系是架构设计中不可忽视的一部分。本文将从Java Web应用程序的角度出发&#xff0c;详细探讨Mapper与Entity的关系及其在技术实现中的作用。 一、Mapper与Entity的基本概念 1.1…

【漫话机器学习系列】052.解释平方和(Explained Sum of Squares, ESS)

解释平方和&#xff08;Explained Sum of Squares, ESS&#xff09; 定义 解释平方和&#xff08;Explained Sum of Squares, ESS&#xff09;是回归分析中用于衡量模型解释能力的一个重要指标。它表示模型通过自变量对因变量的解释程度。ESS 是因变量的预测值与其平均值之间…