【JavaWeb】2. 通用基础代码

以下内容来源:编程导航。

无论在任何后端项目中,都可以复用的代码。

在这里插入图片描述

1、自定义异常

自定义错误码,对错误进行收敛,便于前端统一处理。

💡 这里有 2 个小技巧:

  1. 自定义错误码时,建议跟主流的错误码(比如 HTTP 错误码)的含义保持一致,比如 “未登录” 定义为 40100,和 HTTP 401 错误(用户需要进行身份认证)保持一致,会更容易理解。
  2. 错误码不要完全连续,预留一些间隔,便于后续扩展。

exception 包下新建错误码枚举类:

@Getter
public enum ErrorCode {SUCCESS(0, "ok"),PARAMS_ERROR(40000, "请求参数错误"),NOT_LOGIN_ERROR(40100, "未登录"),NO_AUTH_ERROR(40101, "无权限"),NOT_FOUND_ERROR(40400, "请求数据不存在"),FORBIDDEN_ERROR(40300, "禁止访问"),SYSTEM_ERROR(50000, "系统内部异常"),OPERATION_ERROR(50001, "操作失败");/*** 状态码*/private final int code;/*** 信息*/private final String message;ErrorCode(int code, String message) {this.code = code;this.message = message;}}

一般不建议直接抛出 Java 内置的 RuntimeException,而是自定义一个业务异常,和内置的异常类区分开,便于定制化输出错误信息:

@Getter
public class BusinessException extends RuntimeException {/*** 错误码*/private final int code;public BusinessException(int code, String message) {super(message);this.code = code;}public BusinessException(ErrorCode errorCode) {super(errorCode.getMessage());this.code = errorCode.getCode();}public BusinessException(ErrorCode errorCode, String message) {super(message);this.code = errorCode.getCode();}}

为了更方便地根据情况抛出异常,可以封装一个 ThrowUtils,类似断言类,简化抛异常的代码:

public class ThrowUtils {/*** 条件成立则抛异常** @param condition        条件* @param runtimeException 异常*/public static void throwIf(boolean condition, RuntimeException runtimeException) {if (condition) {throw runtimeException;}}/*** 条件成立则抛异常** @param condition 条件* @param errorCode 错误码*/public static void throwIf(boolean condition, ErrorCode errorCode) {throwIf(condition, new BusinessException(errorCode));}/*** 条件成立则抛异常** @param condition 条件* @param errorCode 错误码* @param message   错误信息*/public static void throwIf(boolean condition, ErrorCode errorCode, String message) {throwIf(condition, new BusinessException(errorCode, message));}
}

2、响应包装类

一般情况下,每个后端接口都要返回调用码、数据、调用信息等,前端可以根据这些信息进行相应的处理。

我们可以封装统一的响应结果类,便于前端统一获取这些信息。

通用响应类:

@Data
public class BaseResponse<T> implements Serializable {private int code;private T data;private String message;public BaseResponse(int code, T data, String message) {this.code = code;this.data = data;this.message = message;}public BaseResponse(int code, T data) {this(code, data, "");}public BaseResponse(ErrorCode errorCode) {this(errorCode.getCode(), null, errorCode.getMessage());}
}

但之后每次接口返回值时,都要手动 new 一个 BaseResponse 对象并传入参数,比较麻烦,我们可以新建一个工具类,提供成功调用和失败调用的方法,支持灵活地传参,简化调用。

public class ResultUtils {/*** 成功** @param data 数据* @param <T>  数据类型* @return 响应*/public static <T> BaseResponse<T> success(T data) {return new BaseResponse<>(0, data, "ok");}/*** 失败** @param errorCode 错误码* @return 响应*/public static BaseResponse<?> error(ErrorCode errorCode) {return new BaseResponse<>(errorCode);}/*** 失败** @param code    错误码* @param message 错误信息* @return 响应*/public static BaseResponse<?> error(int code, String message) {return new BaseResponse<>(code, null, message);}/*** 失败** @param errorCode 错误码* @return 响应*/public static BaseResponse<?> error(ErrorCode errorCode, String message) {return new BaseResponse<>(errorCode.getCode(), null, message);}
}

3、全局异常处理器

为了防止意料之外的异常,利用 AOP 切面全局对业务异常和 RuntimeException 进行捕获:

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(BusinessException.class)public BaseResponse<?> businessExceptionHandler(BusinessException e) {log.error("BusinessException", e);return ResultUtils.error(e.getCode(), e.getMessage());}@ExceptionHandler(RuntimeException.class)public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {log.error("RuntimeException", e);return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误");}
}

4、请求包装类

对于 “分页”、“删除某条数据” 这类通用的请求,可以封装统一的请求包装类,用于接受前端传来的参数,之后相同参数的请求就不用专门再新建一个类了。

分页请求包装类,接受页号、页面大小、排序字段、排序顺序参数:

@Data
public class PageRequest {/*** 当前页号*/private int current = 1;/*** 页面大小*/private int pageSize = 10;/*** 排序字段*/private String sortField;/*** 排序顺序(默认降序)*/private String sortOrder = "descend";
}

删除请求包装类,接受要删除数据的 id 作为参数:

@Data
public class DeleteRequest implements Serializable {/*** id*/private Long id;private static final long serialVersionUID = 1L;
}

5、全局跨域配置

跨域是指浏览器访问的 URL(前端地址)和后端接口地址的域名(或端口号)不一致导致的,浏览器为了安全,默认禁止跨域请求访问。

为了开发调试方便,我们可以通过全局跨域配置,让整个项目所有的接口支持跨域,解决跨域报错。

新建 config 包,用于存放所有的配置相关代码。全局跨域配置代码如下:

@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {// 覆盖所有请求registry.addMapping("/**")// 允许发送 Cookie.allowCredentials(true)// 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突).allowedOriginPatterns("*").allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*").exposedHeaders("*");}
}

编写示例接口

移除 controller 包下的其他代码,让项目干净一些,然后编写一个纯净的 /health 接口用于健康检查:

@RestController
@RequestMapping("/")
public class MainController {/*** 健康检查*/@GetMapping("/health")public BaseResponse<String> health() {return ResultUtils.success("ok");}
}

💡 健康检查是指可以通过访问该接口,来快速验证后端服务是否正常运行,所以该接口的返回值非常简单。

在这里插入图片描述

访问 http://localhost:8123/api/health,看到输出结果,表示后端初始化完成。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

获取IP地区

包 https://packagist.org/packages/geoip2/geoip2#v3.1.0 用composer加载包 composer require geoip2/geoip2 mmdb下载 https://github.com/P3TERX/GeoLite.mmdb?tabreadme-ov-file

企业国外传输大文件到国内该怎么做?

在全球化的商业环境中&#xff0c;企业跨国传输大文件已成为日常运营的重要组成部分。无论是项目合作、数据分析还是文件备份&#xff0c;高效且安全的文件传输对于企业的竞争力和业务连续性至关重要。 企业跨国传输文件的需求重要性 首先&#xff0c;跨国传输大文件能够显著提…

HTML+CSS+JS制作中华传统文化主题网站(内附源码,含5个页面)

一、作品介绍 HTMLCSSJS制作一个中华传统文化主题网站&#xff0c;包含首页、文化艺术页、传统工艺页、文化遗产页、关于我们页等5个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部导航区 包含网站 Logo、主导航菜单&#xff…

stm32week3

stm32学习 二.外设 8.TIM输出比较 OC(output compare)输出比较 输出比较可以通过比较CNT与CCR寄存器值的关系&#xff0c;来对输出电平进行置1、置0、翻转操作&#xff0c;用于输出一定频率和占空比的PWM波形 每个高级定时器和通用定时器都拥有4个输出比较通道 高级定时器的…

学习threejs,导入assimp assimp2json格式的模型

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.AssimpJSONLoader as…

Webstorm整合Tabnine AI 编码工具

1、打开 WebStorm 设置 Windows/Linux: File -> Settings Mac: WebStorm -> Preferences 2、安装插件 选择 Plugins 点击 Marketplace 搜索 "Tabnine" 点击 Install 重启 WebStorm 如果第一种方式在插件中搜索不到Tabnine的话 则通过第二中方式安装 1、访问Tab…

Tableau数据可视化与仪表盘搭建-数据可视化原理

目录 内容 做个小实验 数据如何变成图表 1 2 维度和度量定义 3 度量映射图形&#xff0c;维度负责区分 1 可映射的数据类型 2 可视化字典 3 使用Tableau将数据变成图表(Tableau可视化原理) 1 2 拖拽 3 具体操作 4 总结 内容 点击左下角的工作表 tableau可以自动…

ansible-api分析(Inventory)

一. 简述&#xff1a; 通过ansible 实现系统初始化功能&#xff0c; 为和平台嵌入&#xff0c; 需要通过ansible的api进行功能实现。 准确来说&#xff0c;ansible并没有纯粹的外部接入api功能&#xff0c; 只是官方提供了原生类&#xff0c;用于继承接入&#xff0c;从而实现a…

[Linux]Mysql9.0.1服务端脱机安装配置教程(redhat)

前言 本教程适用于在yum源不可用的LInux主机上安装Mysql的场景。 以redhat系主机做操作示例&#xff0c;debian系主机可参照步骤&#xff0c;将对应的rpm -ivh命令换成dpkg -i。 1. 官网下载安装包 https://dev.mysql.com/downloads/mysql/ 1.1 版本分类 MySQL Enterprise…

【JAVA】Java开发小游戏 - 简单的2D平台跳跃游戏 基本的2D平台跳跃游戏框架,适合初学者学习和理解Java游戏开发的基础概念

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

HTTP/HTTPS ②-Cookie || Session || HTTP报头

这里是Themberfue 上篇文章介绍了HTTP报头的首行信息 本篇我们将更进一步讲解HTTP报头键值对的含义~~~ ❤️❤️❤️❤️ 报头Header ✨再上一篇的学习中&#xff0c;我们了解了HTTP的报头主要是通过键值对的结构存储和表达信息的&#xff1b;我们已经了解了首行的HTTP方法和UR…

Spring Boot 项目自定义加解密实现配置文件的加密

在Spring Boot项目中&#xff0c; 可以结合Jasypt 快速实现对配置文件中的部分属性进行加密。 完整的介绍参照&#xff1a; Spring Boot Jasypt 实现application.yml 属性加密的快速示例 但是作为一个技术强迫症&#xff0c;总是想着从底层开始实现属性的加解密&#xff0c;…

Bash Shell的操作环境

目录 1、路径与指令搜寻顺序 2、bash的进站&#xff08;开机&#xff09;与欢迎信息&#xff1a;/etc/issue&#xff0c;/etc/motd &#xff08;1&#xff09;/etc/issue &#xff08;2&#xff09;/etc/motd 3、bash的环境配置文件 &#xff08;1&#xff09;login与non-…

最好用的图文识别OCR -- PaddleOCR(2) 提高推理效率(PPOCR模型转ONNX模型进行推理)

在实际推理过程中&#xff0c;使用 PaddleOCR 模型时效率较慢&#xff0c;经测试每张图片的检测与识别平均耗时超过 5 秒&#xff0c;这在需要大规模自动化处理的场景中无法满足需求。为此&#xff0c;我尝试将 PaddleOCR 模型转换为 ONNX 格式进行推理&#xff0c;以提升效率。…

51单片机——共阴数码管实验

数码管中有8位数字&#xff0c;从右往左分别为LED1、LED2、...、LED8&#xff0c;如下图所示 如何实现点亮单个数字&#xff0c;用下图中的ABC来实现 P2.2管脚控制A&#xff0c;P2.3管脚控制B&#xff0c;P2.4管脚控制C //定义数码管位选管脚 sbit LSAP2^2; sbit LSBP2^3; s…

mv指令详解

&#x1f3dd;️专栏&#xff1a;https://blog.csdn.net/2301_81831423/category_12872319.html &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 基本语法 主要功能 常用选项详解 1. …

css中的部分文字特性

文章目录 一、writing-mode二、word-break三、word-spacing;四、white-space五、省略 总结归纳常见文字特性&#xff0c;后续补充 一、writing-mode 默认horizontal-tbwriting-mode: vertical-lr; 从第一排开始竖着排&#xff0c;到底部再换第二排&#xff0c;文字与文字之间从…

【JMM】Java 内存模型

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 前言2. JMM 内存模型内容3. JMM 内存模型简单执行示意图 ⚠️ 不要与 JVM 内存分布混为一谈论&#xff0c…

服务器等保测评审计日志功能开启(auditd)和时间校准

操作系统审计日志功能开启auditd CentOS 7 默认已经安装 auditd&#xff0c;如果没有&#xff0c;可以通过以下命令安装&#xff1a; yum install audit systemctl start auditd systemctl enable auditd配置审计规则 配置审计规则。添加所需的审计规则 永久规则文件&#xff1…

Backend - C# EF Core 执行迁移 Migrate

目录 一、创建Postgre数据库 二、安装包 &#xff08;一&#xff09;查看是否存在该安装包 &#xff08;二&#xff09;安装所需包 三、执行迁移命令 1. 作用 2. 操作位置 3. 执行&#xff08;针对visual studio&#xff09; 查看迁移功能的常用命令&#xff1a; 查看…