你的 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 + 断言机制的组合,让你的代码呈现出清晰的三层结构:
- 格式验证层 (
@NotNull、@Min...)→ 注解声明,零代码 - 业务验证层 (
ErrorCode.xxx.assertTrue)→ 一行断言 - 业务逻辑层 → 你真正要写的代码
更多资源
- 📖 JSR380 参数验证
- 📖 断言 + 异常机制
下一篇预告:[开发神器:DebugInOut 插件与调用统计]