Solon

solon.validation

v2.7.1 native </> markdown
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon.validation</artifactId>
</dependency>

1、描述

基础扩展插件,为 solon 提供完整的数据校验能力。支持:

  • 动作注解校验
    • 支持 Context::paramMap 数据校验
    • 支持行为验证,比如重复提交(需要对接)
    • 支持身份验证,比如白名单(需要对接)
  • 参数注解校验
  • 实体注解校验

默认策略,有校验不通过的会马上返回。如果校验所有,需加配置申明(返回的信息结构会略不同):

solon.validation.validateAll: true

能力实现与说明:

加注位置能力实现基础说明
函数基于 @Before Handler 实现对请求上下文里的值做校验(header, param..)
参数基于 @Around Interceptor 实现对函数的参数值本身做校验

2、校验注解清单

注解作用范围说明
Valid控制器类启用校验能力(加在控制器或者控制器基类上)
Validated参数 或 字段校验(参数或字段的类型)实体类上的字段
Date参数 或 字段校验注解的值为日期格式
DecimalMax(value)参数 或 字段校验注解的值小于等于@ DecimalMax指定的value值
DecimalMin(value)参数 或 字段校验注解的值大于等于@ DecimalMin指定的value值
Email参数 或 字段校验注解的值为电子邮箱格式
Length(min, max)参数 或 字段校验注解的值长度在min和max区间内(对字符串有效)
Logined控制器 或 动作校验本次请求主体已登录
Max(value)参数 或 字段校验注解的值小于等于@Max指定的value值
Min(value)参数 或 字段校验注解的值大于等于@Min指定的value值
NoRepeatSubmit控制器 或 动作校验本次请求没有重复提交
NotBlacklist控制器 或 动作校验本次请求主体不在黑名单
NotBlank动作 或 参数 或 字段校验注解的值不是空白
NotEmpty动作 或 参数 或 字段校验注解的值不是空
NotNull动作 或 参数 或 字段校验注解的值不是null
NotZero动作 或 参数 或 字段校验注解的值不是0
Null动作 或 参数 或 字段校验注解的值是null
Numeric动作 或 参数 或 字段校验注解的值为数字格式
Pattern(value)参数 或 字段校验注解的值与指定的正则表达式匹配
Size参数 或 字段校验注解的集合大小在min和max区间内(对集合有效)
Whitelist控制器 或 动作校验本次请求主体在白名单范围内

3、@Valid@Validated 的区别

  • Valid

用于启用校验能力。加在控制器或者控制器基类上。

  • Validated

校验(参数或字段的类型)实体类上的字段。加在参数或字段上。

4、应用示例

//这个注解一定要加类上(或者基类上)
@Valid
@Controller
public class UserController {
    //
    //这里只是演示,用时别乱加
    //
    @NoRepeatSubmit  //重复提交验证
    @Whitelist     //白名单验证
    @Mapping("/user/add")
    public void addUser(
            @NotNull String name, 
            @Pattern("^http") String icon, //注解在参数或字段上时,不需要加 value 属性
            @Validated User user) //实体校验,需要加 @Validated
    { 
        //...
    }
    
    //分组校验
    @Mapping("/user/update")
    public void updateUser(@Validated(UpdateLabel.class) User user){
        //...
    }
}

@Data
public class User {
    @NotNull(groups = UpdateLabel.class) //用于分组校验
    private Long id;
    
    @NotNull
    private String nickname;
    
    @Email  //注解在参数或字段上时,不需要加 value 属性
    private String email;
}

5、需要业务检测对接的四个注解

  • @NoRepeatSubmit 不能重复提交注解
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class NoRepeatSubmitCheckerImpl implements NoRepeatSubmitChecker {
    @Override
    public boolean check(NoRepeatSubmit anno, Context ctx, String submitHash, int limitSeconds) {
        //借用分布式锁,挡住 submitHash 在一定时间内多次进入
        return LockUtils.tryLock(Solon.cfg().appName(), submitHash, limitSeconds);
    }
}
  • @Whitelist 白名单注解(即在一个名单里)
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class WhitelistCheckerImpl implements WhitelistChecker {
    @Override
    public boolean check(Whitelist anno, Context ctx) {
        String ip = ctx.realIp(); //此处以ip为例,其实也可以是任何东西

        //借用业务系统的名单列表,进行检测
        return CloudClient.list().inListOfIp("whitelist",ip);
    }
}
  • @NotBlacklist 非黑名单注解(即不在一个名单里)
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class NotBlacklistCheckerImpl implements NotBlacklistChecker {
    @Override
    public boolean check(NotBlacklist anno, Context ctx) {
        String ip = ctx.realIp(); //此处以ip为例,其实也可以是任何东西

        //借用业务系统的名单列表,进行检测
        return CloudClient.list().inListOfIp("blacklist",ip) == false;
    }
}
  • @Logined 已登录注解
//示例:通过组件模式定义检测器(或通过配置器生产Bean)
@Component
public class LoginedCheckerImpl implements LoginedChecker {

    @Override
    public boolean check(Logined anno, Context ctx, String userKeyName) {
        return ctx.sessionAsLong(Constants.SESSION_USER_ID) > 0;
    }
}

6、更多使用说明

参考:《请求参数校验、及定制与扩展》