Solon详解(六)- Solon的校验扩展框架使用与扩展
Solon详解系列文章:
Solon详解(一)- 快速入门
Solon详解(二)- Solon的核心
Solon详解(三)- Solon的web开发
Solon详解(四)- Solon的事务传播机制
Solon详解(五)- Solon扩展机制之Solon Plugin
Solon详解(六)- Solon的校验扩展框架使用与扩展
在业务的实现过程中,尤其是对外接口开发,我们需要对请求进行大量的验证并返回错误状态码和描述。lombok 框架有很多很赞的注解,但是人家是throw一个异常,这与有些需求不一定能匹配。
该文将介绍Solon的扩展验证框架:solon.extend.validation 的使用和扩展。效果如下:
@XValid
@XController
public class UserController extends VerifyController{
@RepeatSubmit //重复提交验证
@Whitelist //IP白名单验证
@NotNull({"name", "mobile", "icon", "code"}) //非NULL验证
@Numeric({"code"})
@XMapping("/user/add")
public void addUser(String name, @Pattern("^http") String icon, int code, @Pattern("^13\\d{9}$") String mobile){
//...
}
}
相较于 Spring 的 Validator 是争对 Bean,Solon 则是争对 XContext(即http参数)。这点区别非常大,Solon 是在 XAction 执行之前对 http 参数进行校验。
| 注解 | 作用范围 | 说明 |
|---|---|---|
| Date | 参数 | 校验注解的参数值为日期格式 |
| DecimalMax(value) | 参数 | 校验注解的参数值小于等于@ DecimalMax指定的value值 |
| DecimalMin(value) | 参数 | 校验注解的参数值大于等于@ DecimalMin指定的value值 |
| 参数 | 校验注解的参数值为电子邮箱格式 | |
| Length(min, max) | 参数 | 校验注解的参数值长度在min和max区间内 |
| Max(value) | 参数 | 校验注解的参数值小于等于@Max指定的value值 |
| Min(value) | 参数 | 校验注解的参数值大于等于@Min指定的value值 |
| NoRepeatSubmit | 控制器 或 动作 | 校验本次请求没有重复 |
| NotBlank | 动作 或 参数 | 校验注解的参数值不是空白 |
| NotEmpty | 动作 或 参数 | 校验注解的参数值不是空 |
| NotNull | 动作 或 参数 | 校验注解的参数值不是null |
| NotZero | 动作 或 参数 | 校验注解的参数值不是0 |
| Null | 动作 或 参数 | 校验注解的参数值是null |
| Numeric | 动作 或 参数 | 校验注解的参数值为数字格式 |
| Pattern(value) | 参数 | 校验注解的参数值与指定的正则表达式匹配 |
| Whitelist | 控制器 或 动作 | 校验本次请求在白名单范围内 |
| XValid | 控制器 或 动作 | 为控制器 或 动作启用验证能力 |
可作用在 [动作 或 参数] 上的注解,加在动作上时可支持多个参数的校验。
一、定制使用
solon.extend.validation 通过 ValidatorManager,提供了一组定制和扩展接口。
1、@NoRepeatSubmit 改为分布式锁
NoRepeatSubmit 默认使用了本地延时锁。如果是分布式环境,需要定制为分布式锁:
public class NoRepeatLockNew implements NoRepeatLock {
@Override
public boolean tryLock(String key, int seconds) {
//使用分布式锁
//
return LockUtils.tryLock(XWaterAdapter.global().service_name(), key, seconds);
}
}
ValidatorManager.setNoRepeatLock(new NoRepeatLockNew());
2、@Whitelist 实现验证
框架层面没办法为 Whitelist 提供一个名单库,所以需要通过一个接口实现完成对接。
public class WhitelistCheckerNew implements WhitelistChecker {
@Override
public boolean check(Whitelist anno, XContext ctx) {
String ip = IPUtils.getIP(ctx);
return WaterClient.Whitelist.existsOfServerIp(ip);
}
}
ValidatorManager.setWhitelistChecker(new WhitelistCheckerNew());
3、改造校验输出
solon.extend.validation 默认输出 http 400 状态 + json;尝试改改去掉 http 400 状态。
@XConfiguration
public class Config {
@XBean //Solon 的 @XBean 也支持空函数,为其它提运行申明
public void adapter() {
ValidatorManager.globalSet(new ValidatorManager((ctx, ano, rst, message) -> {
ctx.setHandled(true);
if (XUtil.isEmpty(message)) {
message = new StringBuilder(100)
.append("@")
.append(ano.annotationType().getSimpleName())
.append(" verification failed")
.toString();
}
ctx.output(message);
return true;
}));
}
}
二、添一个扩展注解
1、先定义个校验注解 @Date
偷懒一下,直接把自带的扔出来了。只要看着能自己搞就行了:-P
@Target({ElementType.PARAMETER}) //只让它作用到参数,不管作用在哪,最终都是对XContext的校验
@Retention(RetentionPolicy.RUNTIME)
public @interface Date {
@XNote("日期表达式, 默认为:ISO格式") //用XNote注解,是为了用时还能看到这个注释
String value() default "";
String message() default "";
}
2、添加 @Date 的校验器实现类
public class DateValidator implements Validator<Date> {
public static final DateValidator instance = new DateValidator();
@Override
public String message(Date anno) {
return anno.message();
}
@Override
public XResult validate(XContext ctx, Date anno, String name, StringBuilder tmp) {
String val = ctx.param(name);
if (val == null || tryParse(anno, val) == false) {
tmp.append(',').append(name);
}
if (tmp.length() > 1) {
return XResult.failure(tmp.substring(1));
} else {
return XResult.succeed();
}
}
private boolean tryParse(Date anno, String val) {
try {
if (XUtil.isEmpty(anno.value())) {
DateTimeFormatter.ISO_LOCAL_DATE_TIME.parse(val);
} else {
DateTimeFormatter.ofPattern(anno.value()).parse(val);
}
return true;
} catch (Exception ex) {
return false;
}
}
}
3、注册到校验管理器
@XConfiguration
public class Config {
@XBean
public void adapter() {
ValidatorManager.global().register(Date.class, DateValidator.instance);
}
}
4、使用一下
@XValid
@XController
public class UserController extends VerifyController{
@XMapping("/user/add")
public void addUser(String name, @Date("yyyy-MM-dd") String birthday){
//...
}
}
Solon详解(六)- Solon的校验扩展框架使用与扩展的更多相关文章
- Springboot mini - Solon详解(六)- Solon的校验框架使用、定制与扩展
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- Springboot mini - Solon详解(五)- Solon扩展机制之Solon Plugin
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- Solon详解(二)- Solon的核心
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(三)- Solon的web开发
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(七)- Solon Ioc 的注解对比Spring及JSR330
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(八)- Solon的缓存框架使用和定制
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(九)- 渲染控制之定制统一的接口输出
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(十)- 怎么用 Solon 开发基于 undertow jsp tld 的项目?
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
- Solon详解(11)- Mybatis 与 Solon 相亲相爱
Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...
随机推荐
- Hive: Reflect UDF
Reflect UDF JAVA类和方法通常用于处理用户希望在hive中使用的确切的函数.相比与封装一个UDF然后调用这个方法,这些 方法主要通过反射UDF去调用.Reflect使用Java反射去实例 ...
- 算法学习笔记:2-SAT
SAT 是适定性(Satisfiability)问题的简称.一般形式为 k - 适定性问题,简称 k-SAT.而当 \(k>2\) 时该问题为 NP 完全的.所以我们只研究 \(k=2\) 的情 ...
- ASP.NET Core3.x 基础(1)
ASP.NET Core与2.x相比发生的一些变化: 项目结构 Blazor SignalR gRPC 关于Program类:Main方法,在系统执行时就会找到这个Main方法,实际上是配置了ASP. ...
- C++字符串转整形、浮点型stof()、atoi()、strtol()等
头文件:#include<stdlib.h>string str;stof:float val=stof(str);atoi:int val=atoi(str);atol:long val ...
- 2020-04-17:说说redis的rdb原理。假设服务器的内存8g,redis父进程占用了6g,子进程fork父进程后,子父进程总共占用内存12g,如何解决内存不足的问题?(挖)
福哥答案2020-04-18: 这是一道挖坑题.内存占用只会比6g多一点,不会用12g.fork+cow.
- 关于java中jdk的环境变量配置
关于java中jdk的环境变量配置 烦死人,在网上找了很长时间.最终找到了一个方法!现在将其总结帮助后来人. 方法/步骤 1 下载好jdk,并按照提示一步步安装,最后记下jdk所在的安装位置,这里 ...
- 【AHOI 2015】 小岛 - 最短路
描述 西伯利亚北部的寒地,坐落着由 N 个小岛组成的岛屿群,我们把这些小岛依次编号为 1 到 N . 起初,岛屿之间没有任何的航线.后来随着交通的发展,逐渐出现了一些连通两座小岛的航线.例如增加一条在 ...
- 什么是BFC?看这一篇就够了
BFC 定义 BFC(Block formatting context)直译为"块级格式化上下文".它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的 ...
- Url跳转漏洞常见
Url跳转漏洞常见出现点: 1.用户登录.统一身份认证处,认证完后会跳转. 2.用户分享.收藏内容过后,会跳转. 3.跨站点认证.授权后,会跳转. 4.站内点击其它网址链接时,会跳转. Url跳转漏洞 ...
- NOSQL基础
一.mongoDB介绍和使用 1.分布式文件储存数据库,使用C++开发的,可以存储任意数据(文件),允许在服务器端执行脚本,使用JSON形式储存数据{key:value} 2.支持的编程语言有:PHP ...