从零到一构建短链接系统(七)

news2024/11/24 7:42:59

1.convention目录下创建exception目录,并创建AbstractException类,
ClientException类,ServiceException类,RemoteException类

/**
 * 抽象项目中三类异常体系,客户端异常、服务端异常以及远程服务调用异常
 *
 * @see ClientException
 * @see ServiceException
 * @see RemoteException
 */
@Getter
public abstract class AbstractException extends RuntimeException {
    public final String errorCode;
    public final String errorMessage;

    public AbstractException(String message, Throwable throwable, IErrorCode errorCode) {
        super(message, throwable);
        this.errorCode = errorCode.code();
        this.errorMessage = Optional.ofNullable(StringUtils.hasLength(message) ? message : null)
                .orElse(errorCode.message());
    }
}
/**
 * 客户端异常
 */
public class ClientException extends AbstractException {
    public ClientException(IErrorCode errorCode) {
        this(null, null, errorCode);
    }

    public ClientException(String message) {
        this(message, null, BaseErrorCode.CLIENT_ERROR);
    }

    public ClientException(String message, IErrorCode errorCode) {
        this(message, null, errorCode);
    }

    public ClientException(String message, Throwable throwable, IErrorCode errorCode) {
        super(message, throwable, errorCode);
    }

    @Override
    public String toString() {
        return "ClientException{" +
                "code='" + errorCode + "'," +
                "message='" + errorMessage + "'" +
                '}';
    }
}
/**
 * 远程服务调用异常
 */
public class RemoteException extends AbstractException {
    public RemoteException(String message) {
        this(message, null, BaseErrorCode.REMOTE_ERROR);
    }

    public RemoteException(String message, IErrorCode errorCode) {
        this(message, null, errorCode);
    }

    public RemoteException(String message, Throwable throwable, IErrorCode errorCode) {
        super(message, throwable, errorCode);
    }

    @Override
    public String toString() {
        return "RemoteException{" +
                "code='" + errorCode + "'," +
                "message='" + errorMessage + "'" +
                '}';
    }
}
/**
 * 服务端异常
 */
public class ServiceException extends AbstractException {
    public ServiceException(String message) {
        this(message, null, BaseErrorCode.SERVICE_ERROR);
    }

    public ServiceException(IErrorCode errorCode) {
        this(null, errorCode);
    }

    public ServiceException(String message, IErrorCode errorCode) {
        this(message, null, errorCode);
    }

    public ServiceException(String message, Throwable throwable, IErrorCode errorCode) {
        super(Optional.ofNullable(message).orElse(errorCode.message()), throwable, errorCode);
    }

    @Override
    public String toString() {
        return "ServiceException{" +
                "code='" + errorCode + "'," +
                "message='" + errorMessage + "'" +
                '}';
    }
}


2.UserServiceImpl就可以修改为

代码片段实现了UserService接口的一个方法getUserByUsername,该方法用于根据用户名获取用户信息,并返回一个UserRespDTO对象。在方法中有一个判断if (userDO == null)来处理当用户不存在时的情况(userDO对象如果为null,代表数据库中没有匹配的记录)。
如果去掉if (userDO == null)这个判断,当数据库中没有找到匹配的UserDO记录时,userDO变量会被赋值为null。随后的BeanUtils.copyProperties(userDO, result);调用将会失败,因为BeanUtils.copyProperties方法会尝试访问userDO的属性来复制到result对象,如果userDO是null,那么就会引发NullPointerException。


3.result目录下创建Results类,即可简化UserController

4.common目录下创建web目录,再创建GlobalExceptionHandler
全局异常拦截器,需要拦截器的原因在于,我们不可能在代码的逻辑上拦截所有异常,比如如果没写return null就会有空指针异常,这时拦截器可以拦截这样的错误,并报出异常

/**
 * 全局异常处理器
 *
 */
@Component
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 拦截参数验证异常
     */
    @SneakyThrows
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result validExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        FieldError firstFieldError = CollectionUtil.getFirst(bindingResult.getFieldErrors());
        String exceptionStr = Optional.ofNullable(firstFieldError)
                .map(FieldError::getDefaultMessage)
                .orElse(StrUtil.EMPTY);
        log.error("[{}] {} [ex] {}", request.getMethod(), getUrl(request), exceptionStr);
        return Results.failure(BaseErrorCode.CLIENT_ERROR.code(), exceptionStr);
    }

    /**
     * 拦截应用内抛出的异常
     */
    @ExceptionHandler(value = { AbstractException.class })
    public Result abstractException(HttpServletRequest request, AbstractException ex) {
        if (ex.getCause() != null) {
            log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex.toString(),
                    ex.getCause());
            return Results.failure(ex);
        }
        log.error("[{}] {} [ex] {}", request.getMethod(), request.getRequestURL().toString(), ex.toString());
        return Results.failure(ex);
    }

    /**
     * 拦截未捕获异常
     */
    @ExceptionHandler(value = Throwable.class)
    public Result defaultErrorHandler(HttpServletRequest request, Throwable throwable) {
        log.error("[{}] {} ", request.getMethod(), getUrl(request), throwable);
        return Results.failure();
    }

    private String getUrl(HttpServletRequest request) {
        if (StringUtils.isEmpty(request.getQueryString())) {
            return request.getRequestURL().toString();
        }
        return request.getRequestURL().toString() + "?" + request.getQueryString();
    }
}


 

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

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

相关文章

第2章 数据处理伦理

思维导图 2.1 引言 简单来说,伦理是建立在是非观念上的行为准则。伦理准则通常侧重于公平、尊重、责任、诚信、质量、可靠性、透明度和信任等方面。 数据处理伦理指如何以符合伦理准则的方式获取、存储、管理、使用和销毁数据。 核心概念:对人的影响、…

sentry-cli - error: Failed to load .sentryclirc file from project path

Xcode 15.2 warning sentry-cli - error: Failed to load .sentryclirc file from project path (/Users/zhuhongwei/Desktop/pandabill/.sentryclirc)推荐一下刚上线的 App 熊猫小账本,里面有用到这篇博客讲的内容 熊猫小账本 一个简洁的记账 App,用于…

第1章 Iceberg简介

1.1 概述 Iceberg是一个面向大型分析数据集的开放表格格式。它为多种计算引擎,如Spark、Trino、PrestoDB、Flink、Hive和Impala,增加了表格功能,使用一种高性能的表格格式,其工作方式就像一个SQL表一样。 在生产环境中&#xff0…

QT网络编程之实现UDP组播发送和接收

推荐一个不错的人工智能学习网站,通俗易懂,内容全面,作为入门科普和学习提升都不错,分享一下给大家:前言https://www.captainbed.cn/ai 一.UDP通信 1.QT中实现UDP通信主要用到了以下类:QUdpSocket、QHost…

SQLiteC/C++接口详细介绍之sqlite3类(十二)

返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(十一) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(十三) ​37.sqlite3_load_extension 用于在SQLit…

个人网站|基于jsp 技术+ Mysql+Java的个人网站设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java,ssm,springboot的平台设计与实现项目系统开发资源(可…

DC-2 靶场渗透

环境:kali ip:192.168.157.128 靶机:dc-2 ip:192.168.157.129 确保kali和靶机在NAT模式下 1.nmap ip add #查看kali的IP地址 nmap -sP 192.168.157.0/24 #扫描192.168.157.0这个网段下的存活主机 得到到靶机的IP:192.168.15…

网络编程——预备知识

网络编程——预备知识 🍃套接字🌿什么是套接字🌿套接字的类型🌿套接字的位置 🍃IP🍃端口号Port🍃字节序🍃地址信息结构(结构体类型) 🍃套接字 &a…

spring整合Sentinel

安装sentinel: 执行命令; java -jar sentinel-dashboard-1.8.6.jar 注:sentinel的默认端口为8080,容易出现tomcat的冲突。 当端口冲突,可以使用该指令修改sentinel的端口 默认账号和密码都为sentinel Springcloud整合sentinel:…

【MySQL】学习和总结使用列子查询查询员工工资信息

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-5odctDvQ0AHJJc1C {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

java 数据结构 排序算法

目录 排序 插入排序 直接插入排序 希尔排序( 缩小增量排序 ): 直接选择排序 堆排序 交换排序 冒泡排序 快速排序递归 Hoare法 挖坑法 前后指针法 快速排序优化 快速排序非递归 归并排序 归并排序非递归 排序算法复杂度及稳定性分析 计数排序 排序…

YOLO_you only look once

前言 计算机图形学的课程即将结束,我需要提交一份关于YOLO模型的学习报告。在这段时间里,我对YOLO进行了深入的学习和研究,并记录下了我的学习过程和心得体会。本文将详细介绍YOLO模型的原理、优缺点以及应用领域,希望能够为后续…

matlab 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面

1、内容简介 略 65-可以交流、咨询、答疑 2、内容说明 matlab 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面 李雅普洛夫指数谱、相图、分岔图、庞加莱界面 3、仿真分析 略 4、参考论文 略

UE4_调试工具_绘制调试球体

学习笔记,仅供参考! 效果: 步骤: 睁开眼睛就是该变量在此蓝图的实例上可公开编辑。 勾选效果:

函数栈帧的创建和销毁 - 局部变量|函数传参|函数调用|函数返回|图文详解

目录 1.寄存器EBP和ESP 2.函数栈帧的创建 3.函数的调用 4. 函数栈帧的销毁 函数栈帧(function stack frame)是在函数调用期间在栈上分配的内存区域,用于存储函数的局部变量、参数、以及用于函数调用和返回的相关信息。每当函数被调用时&a…

Redis 应用与原理(三)

更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 Redis Cluster 解决方案 基础概念 首先,分析一下主从哨兵模式带来的问题: 在主从 哨兵的模式下,仍然只有一个 Master 节点,当并发请求较大时,哨兵…

config.properties的存放位置在Javaweb和Java工程中的区别

Java项目中:一般是与src平行的设置一个config目录,然后把配置文件放到config目录里面 Javaweb中:一般放到src目录下 顺便补习一下Properties的用法 package config;import java.io.FileInputStream; import java.io.FileOutputStream; impor…

JD商品详情原数据 API 返回值说明

一、应用场景 商品详情原数据API的应用场景广泛而多样。具体来说,它可以被用于以下方面: 1、电商平台数据分析:电商平台可以通过商品详情原数据API提取商品销售数据、质量评分、评论和反馈等信息,从而帮助用户更好地理解市场和竞…

QT charts模块画图

QT charts模块画图 在项目中使用Qt Charts模块,必须在项目的配置文件(.pro文件)添加行语句。 QT += core gui charts或者 QT += core gui QT += charts在需要使用QtCharts的类的头文件或源文件中,包含如下语句 #include <QWidget> #include &…

Java基础 学习笔记六

自增运算符 /* 自加1-- 自减11. 可以出现在变量前&#xff0c;也可以出现在变量后i 可以i 也可以像这种欲奴算符&#xff0c;只有一边有操作数&#xff0c;我们把这种运算符称为 一元运算符a b 这里的 两边有两个操作数&#xff0c;所以这种运算符被称为 二元运算符2. 无论出…