告别 if-else 地狱 —— JSR380 参数验证在 ionet 中的应用

你的 Action 方法长什么样?

很多开发者的业务方法,前一半都是在检查参数:

java 复制代码
// 不使用验证框架的写法
private void createRoom(CreateRoomMessage message) {
    if (message.roomName == null || message.roomName.isEmpty()) {
        throw new RuntimeException("房间名不能为空");
    }
    if (message.roomName.length() > 20) {
        throw new RuntimeException("房间名太长");
    }
    if (message.maxPlayers < 2 || message.maxPlayers > 10) {
        throw new RuntimeException("人数限制不合法");
    }
    if (message.gameMode < 0 || message.gameMode > 3) {
        throw new RuntimeException("游戏模式不合法");
    }
    // 终于可以写业务了...
}

可以看出参数验证不是业务,却写在了业务里面。


JSR380:声明式验证

ionet 支持 JSR380(Bean Validation)规范。你可以在协议类上用注解声明验证规则:

java 复制代码
@ProtobufClass
public class CreateRoomMessage {
    @NotNull(message = "房间名不能为空")
    @Size(min = 1, max = 20, message = "房间名长度需在1-20之间")
    public String roomName;

    @Min(value = 2, message = "至少2人")
    @Max(value = 10, message = "最多10人")
    public int maxPlayers;

    @Min(value = 0, message = "游戏模式不合法")
    @Max(value = 3, message = "游戏模式不合法")
    public int gameMode;
}

现在你的 Action 方法变成了:

java 复制代码
@ActionMethod(RoomCmd.create)
private RoomInfo createRoom(CreateRoomMessage message) {
    // 直接写业务逻辑!参数已经验证通过了
    Room room = roomService.create(message.roomName, message.maxPlayers);
    return room.toInfo();
}

验证失败时,框架自动将错误信息返回给客户端。 你的业务方法里不会出现任何参数检查代码。


常用验证注解

注解 作用 示例
@NotNull 不能为 null @NotNull(message = "不能为空")
@NotEmpty 不能为 null 且不为空字符串 适用于 String
@Size 字符串/集合长度范围 @Size(min=1, max=50)
@Min 最小值 @Min(1)
@Max 最大值 @Max(100)
@Positive 必须为正数 适用于数字类型
@Email 邮箱格式
@Pattern 正则表达式 @Pattern(regexp="[a-zA-Z]+")

与断言机制的配合

JSR380 负责格式层 的验证(数据类型、长度、范围),断言机制负责业务层的验证(用户是否存在、金币是否足够)。

两者配合使用,让你的代码分层更清晰:

java 复制代码
@ProtobufClass
public class BuyMessage {
    @Positive(message = "商品ID必须为正数")
    public int itemId;

    @Min(value = 1, message = "至少购买1个")
    @Max(value = 99, message = "最多购买99个")
    public int count;
}

@ActionMethod(ShopCmd.buy)
private void buyItem(FlowContext flowContext, BuyMessage message) {
    // JSR380 已经验证了 itemId > 0, 1 <= count <= 99

    Item item = itemService.getItem(message.itemId);
    ErrorCode.itemNotFound.assertTrue(item != null);        // 业务断言
    ErrorCode.itemOffSale.assertTrue(item.isOnSale());      // 业务断言
    ErrorCode.goldNotEnough.assertTrue(hasEnoughGold(item)); // 业务断言

    // 纯粹的业务逻辑
    doPurchase(flowContext.getUserId(), item, message.count);
}

格式验证 → 注解完成,业务验证 → 断言完成,剩下的就是纯业务逻辑。


小结

JSR380 + 断言机制的组合,让你的代码呈现出清晰的三层结构:

  1. 格式验证层 (@NotNull、@Min...)→ 注解声明,零代码
  2. 业务验证层 (ErrorCode.xxx.assertTrue)→ 一行断言
  3. 业务逻辑层 → 你真正要写的代码

更多资源

下一篇预告:开发神器:DebugInOut 插件与调用统计

相关推荐
广州灵眸科技有限公司6 小时前
4G 模组开机自连 systemd 服务方案:基于灵眸科技EAI1106--Core-T
运维·服务器·科技
云和数据.ChenGuang6 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠6 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
qq_401700417 小时前
Linux设备树详解
linux·运维·服务器
凯凯姜7 小时前
分布式锁场景问题
分布式
刚入门的大一新生8 小时前
Linux-信号
linux·运维·服务器
silvamux_8 小时前
10款模型写种草笔记:可发布性、返工来源与成本数据缺口复盘
java·数据库·笔记
步行cgn9 小时前
StringHttpMessageConverter 详解:Spring MVC 中字符串读写的默认转换器
java·spring·mvc
摇滚侠9 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 11
java·笔记·python
小蒜学长9 小时前
基于Spring Boot+Vue3的在线医疗咨询系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·在线问诊·在线医疗咨询系统