08-学成在线项目中统一异常处理的规范

项目中的异常处理

规范异常类型

在Service类的业务方法中有很多的参数合法性校验,当请求参数不合法的时候会抛出异常,但此时异常信息只会在控制台输出,前端界面并不会提示用户

实际开发中前端和后端需要做一些约定: 一般将错误提示信息统一以json格式返回给前端,以HTTP状态码决定当前请求是否出错(非200为操作异常)

{
    "timestamp":"2023-02-02T14:42:36.820+00:00",
    // 添加课程时设置一个负数的课程价格会报500异常
    "status":500,
    "error":"Internal Server Error",
    "message":"",
    "path":"/content/course"
}

为了统一处理异常信息,我们需要在业务方法中自定义并规范项目中抛出的异常类型,这样可以便于统一去捕获这一类或几类的异常

  • 对于业务方法中抛出的非项目自定义的异常类型即未知异常,则统一向用户提示指定的错误信息如执行过程异常请重试的

规范了异常类型, 我们还需要去捕获异常信息,使用try/catch方式去捕获代码比较臃肿,可以统一由SpringMVC提供的控制器增强类去完成异常的捕获

在这里插入图片描述

异常处理(base工程)

第一步: 添加依赖,在base基础工程实现统一异常处理,由于各模块依赖了base基础工程所以都可以使用异常处理

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

第二步: 定义一个枚举类CommonError,枚举一些通用的异常信息对象

package com.xuecheng.base.execption;
/**
* @description 通用错误信息
*/
public enum CommonError {
    UNKOWN_ERROR("执行过程异常,请重试"),
    PARAS_ERROR("非法参数"),
    OBJECT_NULL("对象为空"),
    QUERY_NULL("查询结果为空"),
    REQUEST_NULL("请求参数为空");
    private String errMessage;
    public String getErrMessage() {
        return errMessage;
    }
    CommonError(String errMessage) {
        this.errMessage = errMessage;
    }
}

第三步: 自定义项目的异常类型XueChengPlusException

package com.xuecheng.base.execption;
/**
* @description 学成在线项目异常类
*/
public class XueChengPlusException extends RuntimeException {
    private String errMessage;

    public String getErrMessage() {
        return errMessage;
    }
    public XueChengPlusException() {
        super();
    }
    public XueChengPlusException(String errMessage) {
        super(errMessage);
        this.errMessage = errMessage;
    }
    public static void cast(CommonError commonError) {
        throw new XueChengPlusException(commonError.getErrMessage());
    }
    public static void cast(String errMessage) {
        throw new XueChengPlusException(errMessage);
    }
}

第四步: 自定义响应异常信息的模型类

package com.xuecheng.base.execption;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RestErrorResponse implements Serializable {
    private String errMessage;
}

第五步: 定义全局异常处理器去捕获异常信息同时记录异常日志, 将异常信息封装到异常信息的模型类并响应给用户,实现微服务端全局异常处理

  • @ControllerAdvice或@RestControllerAdvice)(类上): 将当前类标识为异常处理的组件
  • @ExceptionHandler(方法或类上): 用于表明方法处理的异常类型,可以指定一个或多个
  • @ResponseStatus(方法或类上): 标记捕获异常的方法或类指定发生异常时异常处理器向前端响应的状态码和原因
package com.xuecheng.base.execption;
/**
* @description 全局异常处理器
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler(XueChengPlusException.class)// 处理项目自定义异常类型
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 该异常枚举对象的错误码为500
    public RestErrorResponse customException(XueChengPlusException exception) {
        log.error("系统异常:{}", exception.getErrMessage());
        return new RestErrorResponse(exception.getErrMessage());
    }

    @ResponseBody
    @ExceptionHandler(Exception.class)// 未知类型的异常
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)// 该异常枚举对象的错误码为500
    public RestErrorResponse exception(Exception exception) {
        log.error("系统异常:{}", exception.getMessage());
        return new RestErrorResponse(exception.getMessage());
    }
}

异常处理测试(api工程)

第一步: 在内容管理服务的api工程中添加base工程的依赖

<dependency>
    <groupId>com.xuecheng</groupId>
    <artifactId>xuecheng-plus-base</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

第二步: 当业务方法中出现异常时抛出项目自定义的异常类型,这里以新增课程的业务方法为例进行代码修改

@Override
public CourseBaseInfoDto createCourseBase(Long companyId,AddCourseDto dto) {
    //合法性校验
    if (StringUtils.isBlank(dto.getName())) {
        throw new XueChengPlusException("课程名称为空");
    }

    if (StringUtils.isBlank(dto.getMt())) {
        throw new XueChengPlusException("课程分类为空");
    }

    if (StringUtils.isBlank(dto.getSt())) {
        throw new XueChengPlusException("课程分类为空");
    }

    if (StringUtils.isBlank(dto.getGrade())) {
        throw new XueChengPlusException("课程等级为空");
    }

    if (StringUtils.isBlank(dto.getTeachmode())) {
        throw new XueChengPlusException("教育模式为空");
    }

    if (StringUtils.isBlank(dto.getUsers())) {
        throw new XueChengPlusException("适应人群");
    }	

    if (StringUtils.isBlank(dto.getCharge())) {
        throw new XueChengPlusException("收费规则为空");
    }
    if(charge.equals("201001")){
        if(courseMarketNew.getPrice() ==null || courseMarketNew.getPrice().floatValue()<=0){
            throw new XueChengPlusException("课程的价格不能为空并且必须大于0");
        }
    }
}

第三步: 使用HTTP Client进行测试,故意将收费课程价格设置为负数, 查看捕获到的响应信息

在这里插入图片描述

POST http://localhost:53040/content/course

HTTP/1.1 500 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 03 Feb 2023 02:32:20 GMT
Connection: close

{
  "errMessage": "课程设置了收费,价格不能为空,且必须大于0"
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

统计元音字母c语言

以下是一个简单的C语言程序&#xff0c;用于统计一段文本中的元音字母数量&#xff1a; #include <stdio.h>#include <string.h>int main() { char str[1000]; int vowels 0; printf("请输入一段文本&#xff1a;\n"); fgets(str, siz…

蓝桥杯day02——Fizz Buzz

1、题目 给你一个整数 n &#xff0c;找出从 1 到 n 各个整数的 Fizz Buzz 表示&#xff0c;并用字符串数组 answer&#xff08;下标从 1 开始&#xff09;返回结果&#xff0c;其中&#xff1a; answer[i] "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。answer[i] &…

ESP-Mesh-Lite 用户指南

ESP-MESH-LITE 本指南提供有关 Mesh-Lite 协议的介绍。 概述 ESP-MESH-LITE 是一套建立在 Wi-Fi 协议之上的网络协议。ESP-MESH-LITE 允许分布在大范围区域内&#xff08;室内和室外&#xff09;的大量设备&#xff08;下文称节点&#xff09;在同一个 WLAN&#xff08;无线…

工业园区重金属废水深度处理工程项目,稳定出水0.1mg/l

随着环保要求不断提高&#xff0c;工业废水处理已成为众多企业的必修课。然而在工业生产中&#xff0c;如何有效处理含有重金属的废水成为了一个关键的挑战。 重金属废水是指含有汞、铅、铜、镉、锌、镍等有毒有害物质的废水&#xff0c;来源于矿山开采、金属冶炼、电镀、印刷线…

2024年申报国自然项目基金撰写及技巧

随着社会经济发展和科技进步&#xff0c;基金项目对创新性的要求越来越高。申请人需要提出独特且有前瞻性的研究问题&#xff0c;具备突破性的科学思路和方法。因此&#xff0c;基金项目申请往往需要进行跨学科的技术融合。申请人需要与不同领域结合&#xff0c;形成多学科交叉…

20世纪30年代的大危机

背景 1929年9月&#xff0c;美国财政部部长安德鲁梅隆向公众保证“现在没有担心的理由&#xff0c;这一繁荣的高潮将会继续下去”。 当时流行的一首儿歌&#xff1a;“梅隆拉响汽笛&#xff0c;胡佛敲起钟&#xff0c;华尔街发出信号&#xff0c;美国往地狱里冲&#xff01;”…

Dropdown下拉菜单(antd-design组件库)简单用法和禁用菜单

1.Dropdown下拉菜单 向下弹出的列表。 2.何时使用 当页面上的操作命令过多时&#xff0c;用此组件可以收纳操作元素。点击或移入触点&#xff0c;会出现一个下拉菜单。可在列表中进行选择&#xff0c;并执行相应的命令。 用于收罗一组命令操作。 Select 用于选择&#xff0c;而…

西南科技大学信号与系统A实验三(线性连续时间系统的分析)

一、实验目的 1.掌握用 matlab 分析系统时间响应的方法 2.掌握用 matlab 分析系统频率响应的方法 3.掌握系统零、极点分布与系统稳定性关系 二、实验原理 1. 系统函数 H(s) 系统函数:系统零状态响应的拉氏变换与激励的拉氏变换之比. H(s)=R(s)/E(s) 在 matlab 中可采用…

geemap学习笔记016:获取图像的基本属性和描述性信息

前言 遥感数据中通常包含众多信息&#xff0c;例如图像获取的时间、云覆盖量、以及每个波段的最大值最小值等等。 1 导入库并显示地图 import ee import geemapMap geemap.Map() Map2 添加图像数据 centroid ee.Geometry.Point([-122.4439, 37.7538]) #创建一个点坐标lan…

java编程:数组代表着苹果期货在 9 天内的价格变化,其中第 n 个元素是苹果在第 n 天的 价格,你可以进行最多三次交易,设计算法,9 天内赚到最多的钱

1 题目 编程题&#xff1a;下面的数组代表着苹果期货在 9 天内的价格变化&#xff0c;其中第 n 个元素是苹果在第 n 天的 价格&#xff0c;你可以进行最多三次交易&#xff0c;设计一个算法&#xff0c;9 天内如何赚到最多的钱&#xff1f;价格数组&#xff1a; [8, 9, 2, 5, …

DS八大排序之直接插入排序和希尔排序

前言 我们前面几期介绍了线性和非线性的基本数据结构。例如顺序表、链表、栈和队列、二叉树等~&#xff01;本期和接下来的几期我们来详解介绍各个排序的概念、实现以及性能分析&#xff01; 本期内容 排序的概念以及其运用 常见的排序算法 直接插入排序 希尔排序 一、排序的…

Flutter开发type ‘Future<int>‘ is not a subtype of type ‘int‘ in type cast错误

文章目录 问题描述错误源码 问题分析解决方法修改后的代码 问题描述 今天有个同事调试flutter程序时报错&#xff0c;问我怎么解决&#xff0c;程序运行时报如下错误&#xff1a; type ‘Future’ is not a subtype of type ‘int’ in type cast 错误源码 int order Databas…

聚观早报 |红魔9 Pro开卖;真我GT5 Pro定档

【聚观365】11月29日消息 红魔9 Pro开卖 真我GT5 Pro定档 一加12镜头细节公布 Redmi K70 Pro将搭载夜枭算法 苹果Vision Pro头显下月量产 红魔9 Pro开卖 红魔电竞旗舰最新力作——红魔9 Pro系列正式发布。作为一款全能电竞旗舰&#xff0c;该机搭载了第三代骁龙8移动平台…

【九】linux下部署frp客户端服务端实践

linux下部署frp客户端服务端实践 简介&#xff1a; 今天有一个这样的需求&#xff0c;部署在公司内部局域网虚拟机上的服务需要在外网能够访问到&#xff0c;这不就是内网穿透的需求吗&#xff0c;之前通过路由器实现过&#xff0c;现在公司这块路由器不具备这个功能了&#x…

Java后端开发——JDBC(万字详解)

Java后端开发——JDBC&#xff08;万字详解&#xff09; 今日目标 掌握JDBC的的CRUD理解JDBC中各个对象的作用掌握Druid的使用 1&#xff0c;JDBC概述 在开发中我们使用的是java语言&#xff0c;那么势必要通过java语言操作数据库中的数据。这就是接下来要学习的JDBC。 1.1 …

【PHP】MySQL简介与MySQLi函数(含PHP与MySQL交互)

文章目录 一、MySQL简介二、MySQLi函数1. 开启mysqli扩展&#xff1a;2. PHP MySQLi扩展的常用函数 三、PHP与MySQL交互0. 准备1. 创建连接&#xff08;mysqli_connect() &#xff09;连接mysql语法 2. 选择数据库&#xff08;mysqli_select_db()&#xff09;3. 在php中操作数据…

【burpsuite安全练兵场-客户端16】测试WebSockets安全漏洞-3个实验(全)

前言&#xff1a; 介绍&#xff1a; 博主&#xff1a;网络安全领域狂热爱好者&#xff08;承诺在CSDN永久无偿分享文章&#xff09;。 殊荣&#xff1a;CSDN网络安全领域优质创作者&#xff0c;2022年双十一业务安全保卫战-某厂第一名&#xff0c;某厂特邀数字业务安全研究员&…

微服务--03--OpenFeign 实现远程调用 (负载均衡组件SpringCloudLoadBalancer)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 OpenFeign其作用就是基于SpringMVC的常见注解&#xff0c;帮我们优雅的实现http请求的发送。 RestTemplate实现了服务的远程调用 OpenFeign快速入门负载均衡组件Spr…

深入redis过程-命令

目录 通用命令 get set keys exists del expire key seconds ttl type 常用数据结构 String类型 SET GET MSET MGET INCR INCRBY INCRBYFLOAT SETNX SETEX Hash类型 HSET key field value HGET key field HMSET HMGET HGETALL HKEYS HVALS HINCRB…

Redis队列stream,Redis多线程详解

Redis 目前最新版本为 Redis-6.2.6 &#xff0c;会以 CentOS7 下 Redis-6.2.4 版本进行讲解。 下载地址&#xff1a; https://redis.io/download 安装运行 Redis 很简单&#xff0c;在 Linux 下执行上面的 4 条命令即可 &#xff0c;同时前面的 课程已经有完整的视…