Knife4j 接口文档从配置到上线

Knife4j 接口文档 第1步:目标说明 — 打造可交互的 API 文档 后端写完接口,前端过来问"这个参数什么意思"“返回字段有哪些"“能不能让我直接调一下看看效果”——这种场景写过的都懂。 Swagger 就是来解决这个问题的。它能根据代码里的注解自动生成接口文档页面,前端直接在页面上看字段说明、调接口、看返回,不用再追着后端问。而 Knife4j 是 Swagger 的增强 UI,比原生 Swagger UI 好看得多,还支持离线文档导出、全局参数设置、接口排序等实用功能。 本教程基于 Mall 商城项目的真实配置,从零开始搭建一套 Knife4j + Swagger 接口文档,目标是让读者看完就能在自己的项目里用起来。 最终效果:访问 Knife4j 页面,能看到按模块分组的接口列表,点开任意接口能看到请求参数、响应示例,还能直接在页面上填入 Authorization 请求头,在线调试接口。 第2步:前置条件 开始之前,先确认项目环境满足以下条件。 条件 要求 验证命令 JDK 1.8+ java -version Maven 3.6+ mvn -v Spring Boot 2.x 查看 pom.xml 中 spring-boot-starter-parent 版本 现有 Spring Boot Web 项目 已有 Controller 项目中存在 @RestController 类 ⚠️ 新手提示:Knife4j 3.0.2 基于 Springfox 3.0.0,兼容 Spring Boot 2.x。如果是 Spring Boot 3.x 项目,需要使用 knife4j-openapi3-spring-boot-starter 4.x 版本,注解包名也从 io.swagger.annotations 变为 io.swagger.v3.oas.annotations,差异较大,本教程不涉及。 ...

一月 11, 2023 · 6 分钟 · 1108 字 · yaomingye

SpringBoot gRPC 全操作指南

SpringBoot gRPC 实战 📖 前置阅读:本文假设读者已掌握 Protobuf 语法和 gRPC 四种调用模式的概念。如果还不熟悉,建议先阅读 Protobuf 语法精讲与 gRPC 概念。 🎯 第一步:目标说明 上一篇用 protoc 写了 .proto 文件,手动编译生成了 Java 代码。接下来把这一切接入 SpringBoot——用 @GrpcService 暴露 gRPC 服务,用 @GrpcClient 注入远程代理,四种 RPC 模式全部用代码跑通。 📋 第二步:前置条件 前置项 具体要求 验证命令 JDK 17+ java -version SpringBoot 3.x mvn dependency:tree | grep spring-boot protoc 3.25+ (Maven 插件会自动下载) — 前置知识 Protobuf 语法、gRPC 四种模式概念 — 🔧 第三步:项目结构与依赖 3.1 多模块 Maven 项目 grpc-demo ├── pom.xml # 父 POM ├── grpc-api/ # proto 文件 + 生成的 Java 代码 │ ├── pom.xml # 有 protobuf-maven-plugin │ └── src/main/proto/ │ └── order.proto ├── grpc-server/ # gRPC 服务端——实现业务逻辑 │ ├── pom.xml # 依赖 grpc-api │ └── src/main/java/... └── grpc-client/ # gRPC 客户端——调用远程服务 ├── pom.xml # 依赖 grpc-api └── src/main/java/... 为什么要把 proto 放在独立模块? 服务端和客户端都依赖 proto 生成的 Java 代码——放独立模块中双方共享编译结果,而不是各自编译一份。 ...

十一月 29, 2022 · 8 分钟 · 1495 字 · yaomingye

Jackson vs Fastjson2 终极对比

Jackson vs Fastjson2 📖 前置阅读:本文假设读者已经阅读过前两篇——如果还不熟悉 Jackson 或 Fastjson2,建议先阅读 序列化本质与 Jackson 全操作指南 和 Fastjson 进化史:从 1.x 漏洞到 Fastjson2。 一、⚡ 同一个对象,两种写法 先在同一个 Order 类上对比两套注解——直观感受差异: // ===== Jackson 写法 ===== @JsonPropertyOrder({"order_id", "user_id", "product_name", "amount", "create_time"}) @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) public class Order { @JsonProperty("order_id") // Jackson: 改字段名 private Long orderId; @JsonProperty("user_id") private Long userId; @JsonProperty("product_name") private String productName; @JsonFormat(shape = JsonFormat.Shape.STRING) // Jackson: 金额用字符串 private BigDecimal amount; @JsonIgnore // Jackson: 忽略字段 private String internalNote; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") // Jackson: 日期格式 private LocalDateTime createTime; } // ===== Fastjson2 写法 ===== @JSONType(orders = {"order_id", "user_id", "product_name", "amount", "create_time"}) public class Order { @JSONField(name = "order_id") // Fastjson2: 改字段名 private Long orderId; @JSONField(name = "user_id") private Long userId; @JSONField(name = "product_name") private String productName; @JSONField(serializeFeatures = JSONWriter.Feature.WriteBigDecimalAsPlain) private BigDecimal amount; // Fastjson2: 金额不用科学计数法 @JSONField(serialize = false) // Fastjson2: 忽略字段 private String internalNote; @JSONField(format = "yyyy-MM-dd HH:mm:ss") // Fastjson2: 日期格式 private LocalDateTime createTime; } Facjson2 不需要 @JsonIgnoreProperties——它默认忽略未知字段。Jackson 必须在每个类上加这个注解或全局配置。对于有 50+ 个 DTO 类的项目来说,这少写不少样板。 ...

十一月 27, 2022 · 5 分钟 · 875 字 · yaomingye

Fastjson 进化史:从 1.x 漏洞到 Fastjson2

Fastjson 进化史 📖 前置阅读:本文假设读者已理解序列化的基本概念和 JSON 序列化工具的用法。如果还不熟悉,建议先阅读 序列化本质与 Jackson 全操作指南。 一、⚡ Fastjson 曾经有多火 Fastjson 是阿里巴巴 2011 年开源的 JSON 序列化库。在 Jackson 还比较沉重、Gson 性能一般的年代,Fastjson 凭三个特点迅速占领了国内 Java 项目: 卖点 具体表现 快 号称"Java 语言最快的 JSON 处理库"——字节码生成 + ASM 动态优化,比 Jackson 快 2x API 简洁 JSON.toJSONString(obj) 一行搞定——比 Jackson 的 ObjectMapper 样板代码少 阿里出品 阿里巴巴开源——国内 Java 圈号召力最强背书 最火的那些年,几乎所有国内 Java 项目引入 Fastjson——Dubbo、RocketMQ、Nacos 内部都依赖了它。 二、💣 autoType:从"核心卖点"到"最大漏洞" 2.1 autoType 是什么 Fastjson 有一个 Jackson 没有的独特功能——autoType。它的作用是:JSON 中有一个 @type 字段,Fastjson 根据它自动反序列化为对应的 Java 类。 // Fastjson 的 autoType 机制 // 序列化时——自动写入类的全限定名 String json = JSON.toJSONString(order); // 结果:{"@type":"com.example.Order","orderId":10001,"amount":6999.00} // ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ // @type 字段记录了类的全限定名 // 反序列化时——根据 @type 字段自动还原为正确的子类型 // JSON 数据:"{\"@type\":\"com.example.Order\",\"orderId\":10001}" // 即使你只声明为 Object,Fastjson 也能还原出 Order 对象 Object obj = JSON.parse(json); // 实际返回 Order 实例 这个功能在 Jackson 中需要 @JsonTypeInfo 注解手动声明——Fastjson 默认自动开启。 ...

十一月 26, 2022 · 5 分钟 · 1055 字 · yaomingye

序列化本质与 Jackson 全操作指南

序列化本质与 Jackson 一、⚡ 序列化是什么:Java 对象和 JSON 之间的翻译官 日常写的代码里全是 Java 对象——Order、User、Product。但网络传输只能传二进制/文本,数据库只能存文本,前端浏览器只认得 JSON。怎么把 Java 对象变成 JSON、再把 JSON 变回 Java 对象?这就是序列化和反序列化: 序列化(Serialization): Java 对象 → JSON / XML / 二进制 反序列化(Deserialization): JSON / XML / 二进制 → Java 对象 如果不做序列化,你就得手动拼 JSON: // 没有序列化工具——手动拼 JSON(又臭又长) public String orderToJson(Order order) { return "{" + "\"orderId\":" + order.getOrderId() + "," + "\"userId\":" + order.getUserId() + "," + "\"productName\":\"" + escape(order.getProductName()) + "\"," + "\"amount\":" + order.getAmount() + "}"; } // 手写这段代码的时候,你就知道自己需要一个序列化工具了 序列化框架做的事就是自动完成这个转换——你要做的只是加几个注解、调一行方法。 ...

十一月 25, 2022 · 7 分钟 · 1368 字 · yaomingye

SpringBoot Dubbo 全操作指南

SpringBoot Dubbo 📖 前置阅读:本文假设读者已理解 Dubbo 的核心概念(Registry、Provider、Consumer、RPC 调用链路)。如果还不熟悉,建议先阅读 Dubbo 核心架构与 RPC 模型。 🎯 第一步:目标说明 上一篇用原生 Dubbo + Spring XML 写了 <dubbo:service>、<dubbo:reference>、<dubbo:registry>。SpringBoot 时代不需要那些 XML——dubbo-spring-boot-starter 用两个注解 + 一套 yml 配置替代全部 XML。 读完这篇会掌握: dubbo-spring-boot-starter 环境搭建——依赖 + yml 配置 @DubboService——暴露服务,替代 <dubbo:service> @DubboReference——引用远程服务,替代 <dubbo:reference> dubbo 协议 vs triple 协议——什么时候用哪个 Hessian2 / Fastjson2 序列化配置 Nacos 注册中心的 SpringBoot 集成 📋 第二步:前置条件 前置项 具体要求 验证命令 JDK 17+(8+ 也兼容) java -version SpringBoot 3.x(文中用 3.2) mvn dependency:tree | grep spring-boot Nacos 2.3.0(单机即可) docker ps | grep nacos 前置知识 Registry/Provider/Consumer 概念 — 确认 Nacos 在跑: ...

十一月 20, 2022 · 6 分钟 · 1213 字 · yaomingye

SpringBoot Kafka 全操作指南

SpringBoot Kafka 实战 📖 前置阅读:本文假设读者已理解 Kafka 的核心概念(Broker、Topic、Partition、ConsumerGroup、Offset)。如果还不熟悉,建议先阅读 Kafka 核心架构与日志存储模型。 🎯 第一步:目标说明 上一篇用原版 Kafka Java Client 写了 KafkaProducer + KafkaConsumer。和 RabbitMQ、RocketMQ 一样——真实的 SpringBoot 项目里不需要那些样板代码。spring-kafka 帮我们处理了连接管理、Producer 生命周期、Consumer 线程池、Offset 提交。 读完这篇会掌握: KafkaTemplate 三种发送方式(同步/异步/回调) @KafkaListener 注解消费——单条和批量 JSON 序列化全链路配置——Producer 端 JsonSerializer + Consumer 端 JsonDeserializer Producer 配置:acks、retries、batch.size、linger.ms、compression.type Consumer 配置:group.id、auto.offset.reset、enable.auto.commit、max.poll.records 📋 第二步:前置条件 前置项 具体要求 验证命令 JDK 17+(8+ 也兼容) java -version SpringBoot 3.x(文中用 3.2) mvn dependency:tree | grep spring-boot Kafka 3.7.0 KRaft 模式(单节点即可) docker ps | grep kafka 前置知识 Broker/Topic/Partition/ConsumerGroup/Offset 概念 — 确认 Kafka 在跑: ...

十一月 14, 2022 · 8 分钟 · 1619 字 · yaomingye

SpringBoot RocketMQ 全操作指南

SpringBoot 集成 RocketMQ:从发送到消费 📖 前置阅读:本文假设读者已理解 RocketMQ 的核心概念(NameServer、Broker、Topic、Queue、ConsumerGroup)。如果还不熟悉,建议先阅读 RocketMQ 核心架构与消息模型。 Part 1:概念与前置 1.1 本文目标 上一篇用原版 RocketMQ Java Client 写了 DefaultMQProducer + DefaultMQPushConsumer。真实的 SpringBoot 项目里不需要那么多样板代码——rocketmq-spring-boot-starter 帮你处理了 NameServer 连接、Producer 启动、Consumer 注册。 读完这篇会掌握: MqHelper 封装——为什么要在 RocketMQTemplate 上再包一层,asyncSend + SendCallback 的真实用法 30 分钟延迟取消订单——RocketMQ 内置 delayLevel 的完整实战流程,和 RabbitMQ 方案的对比 @RocketMQMessageListener 消费者——MessageExt 手动反序列化 vs 泛型自动解析,以及三个真实业务消费者 Domain Entity 直传——为什么不做 DTO 转换,以及什么情况下不能这样做 双 MQ 基础设施先行——RabbitMQ 拓扑已就绪但全用 RocketMQ 的设计决策 1.2 前置条件 前置项 具体要求 验证命令 JDK 17+(8+ 也兼容) java -version SpringBoot 3.x(文中用 3.2) mvn dependency:tree | grep spring-boot RocketMQ 5.1.4(NameServer + Broker 都在运行) docker ps | grep rocketmq 前置知识 NameServer/Broker/Topic/Queue 概念 — 确认 RocketMQ 在跑: ...

十一月 8, 2022 · 16 分钟 · 3233 字 · yaomingye

SpringBoot RabbitMQ 全操作指南

SpringBoot 集成 RabbitMQ:从发送到消费 📖 前置阅读:本文假设读者已理解 RabbitMQ 的核心概念(Exchange、Queue、Binding、RoutingKey)和四种交换机类型。如果还不熟悉,建议先阅读前两篇: RabbitMQ 核心概念与 AMQP 协议 交换机类型完全指南 Part 1:概念与前置 1.1 本文目标 前两篇用 RabbitMQ 原生 Java Client 写了所有代码——channel.basicPublish、channel.basicConsume、手动 basicAck。理解底层是正确的,但真正进项目时,Spring AMQP 帮我们做了 90% 的重复工作。 读完这篇会掌握: 用 RabbitTemplate 一行代码发消息(替代 channel.basicPublish 那一大堆) 用 @RabbitListener 注解收消息(替代手动 basicConsume + DeliverCallback) 用 Jackson2JsonMessageConverter 自动序列化/反序列化 Java 对象 用 @Bean + 声明式配置 管理 Exchange/Queue/Binding(替代每次启动时 channel.exchangeDeclare) 三种交换机在 Spring 中的完整示例代码(Direct / Fanout / Topic) 手动 ACK 的配置和坑 1.2 前置条件 前置项 具体要求 验证命令 JDK 17+(8+ 也兼容) java -version Maven 3.6+ mvn -v SpringBoot 3.x(文中用 3.2) mvn dependency:tree | grep spring-boot RabbitMQ 3.12+(management 版) docker ps | grep rabbitmq 前置知识 前两篇的 Exchange/Queue/Binding/RoutingKey 概念 — 确认 RabbitMQ 在跑: ...

十一月 3, 2022 · 13 分钟 · 2677 字 · yaomingye

Redis + Caffeine 双层缓存:降级与容错

Redis + Caffeine 双层缓存 📖 前置阅读:本文是缓存架构的进阶级文章,假设读者已经掌握了 Redis 的基础操作和 Caffeine 本地缓存的 API。如果还不熟悉,建议先阅读: SpringBoot Redis 全操作指南 —— Redis 实战篇 Caffeine 核心与 SpringBoot 集成 —— Caffeine 入门篇 一、⚡ 问题切入:凌晨三点,Redis 挂了 凌晨三点,Redis 内存用满——大量的 TTL 同时到期 + 新一波定时任务写入,导致内存 OOM,Redis 进程被系统 kill。你的服务所有缓存请求全部报错,瞬间全部穿透到 MySQL,数据库连接池耗尽,整个系统不可用。 值班群炸了。你翻日志发现——服务启动时所有 @Cacheable 都配置了 Redis,Redis 一挂连个兜底的都没有。 Redis 是高可用的——有哨兵(Sentinel)、有集群(Cluster),官方说可用性能到 99.99%。但 99.99% 意味着一年有将近 1 小时的不可用时间。这 1 小时如果发生在双十一,后果就不是"维护了一次",而是"事故"。 本地缓存的价值不只是"快",更是 Redis 挂了时的最后一道防线。就算 Redis 是全宇宙最高可用的服务,网络也可能抖——交换机故障、机房间专线断掉、Kubernetes 网络策略变更——这些事情的发生概率比 Redis 自身故障高得多。 本篇要解决的问题:构建 Redis(远程)+ Caffeine(本地)双层缓存架构,把 Redis 的不可用当成"迟早会发生的事"来设计,而不是寄望于它不会发生。 📌 真实场景:数据字典——最简单的双层缓存 在进入复杂架构之前,先看一个真实项目里怎么用 Spring Cache + Caffeine + Redis 做双层缓存。不是所有场景都需要 200 行的 TieredCacheManager——有时候 3 行配置 + 1 个注解就够了。 ...

十月 31, 2022 · 11 分钟 · 2341 字 · yaomingye
Cat Radio