在业务的实现过程中,尤其是对外接口开发,我们需要对请求进行大量的验证并返回错误状态码和描述。lombok 框架有很多很赞的注解,但是人家是throw一个异常,这与有些需求不一定能匹配。

该文将基于Solon的一些扩展基础,简单的实现一套定制的业务验证机制。效果如下:


@XController
public class UserController extends VerifyController{
@RepeatSubmit //重复提交验证
@Whitelist //IP白名单验证
@NotNull({"name", "mobile", "icon", "code"}) //非NULL验证
public void addUser(UserModel user){
//...
}
}

一、定制开始

1、先定义一组验证注解

@Inherited
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotNull {
String[] value();
} @Inherited
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Whitelist {
} //... 更多略

2、然后,定义一个验证用的拦截器

//
//Solon里的所有拦截器,也都是 XHandler
//
public class VerifyInterceptor implements XHandler {
@Override
public void handle(XContext ctx) throws Throwable {
//获取上下文中的XAction
//
XAction action = ctx.attr("action");
if (action != null) {
handle0(ctx, action);
}
} protected void handle0(XContext ctx, XAction action) throws Throwable {
//这里的顺序,要与业务的期望顺序匹配 //白名单
checkWhitelist(ctx, action); //不能为Null
checkNotNull(ctx, action); //...更多略
} protected void checkWhitelist(XContext ctx, XAction action) throws Throwable{
if(ctx.getHandled()){
return;
} Whitelist anno = action.method().getAnnotation(Whitelist.class);
if (anno != null) {
String ip = IpUtils.getIP(ctx);
if (WhitelistApi.existsOfServerIp(ip) == false) {
ctx.setHandled(true);
ctx.render(UapiCodes.CODE_16);
}
}
} protected void checkNotNull(XContext ctx, XAction action) throws Throwable{
if(ctx.getHandled()){
return;
} NotNull anno = action.method().getAnnotation(NotNull.class);
if (anno != null) {
checkParamsIsOk(ctx, false, anno.value());
}
}
}

3、再是,定义一个支持验证的控制器基类

//
// 创建一个有验证拦截器的基类;@XBefore 注解是可继承的...
//
@XBefore({VerifyInterceptor.class})
public class VerifyController { }

完工了

二、附:关于 XContext 的部分扩展属性

Solon 的上下文对象:XContext,有一组可扩展属性的接口:attr(), attrSet(), attrMap()。用于记录处理过程中的数据或对象。

以下是框架在运行过程中已记录的扩展属性:

扩展属性 说明
ctx.attr("controller") 获取当前控制器
ctx.attr("action") 获取当前活动
ctx.result 获取当前活动的执行结果,可用于统一的业务日志记录
ctx.attr("error") 获取当前错误
ctx.attr("output") 获取当前序列化输出,可用于统一的业务日志记录

Solon详解(六)- 定制业务级别的验证注解的更多相关文章

  1. Springboot mini - Solon详解(六)- Solon的校验框架使用、定制与扩展

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  2. Solon详解(六)- Solon的校验扩展框架使用与扩展

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  3. Solon详解(八)- Solon的缓存框架使用和定制

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  4. Springboot mini - Solon详解(八)- Solon的缓存框架使用和定制

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  5. Solon详解(九)- 渲染控制之定制统一的接口输出

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  6. Solon详解(11)- Mybatis 与 Solon 相亲相爱

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  7. Solon详解(十)- 怎么用 Solon 开发基于 undertow jsp tld 的项目?

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  8. Springboot mini - Solon详解(四)- Solon的事务传播机制

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  9. Springboot mini - Solon详解(七)- Solon Ioc 的注解对比Spring及JSR330

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

随机推荐

  1. LFM oversea投资笔记、思摩尔、移卡、建业新生活、鑫苑物业

    LFM oversea 1.公司简介 2.业务展望 3. 投资策略 LFM oversea介绍 LFM oversea是在开曼成立的投资基金, 专注于中国优质企业在香港和美国IPO过程中的 基石.锚定 ...

  2. Day10_ElasticSearch

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"乐优商城"获取视频和教程资料! b站在线视频 老师的码 ...

  3. 使用 MySQLi 和 PDO 向 MySQL 插入多条数据

    PHP MySQL 插入多条数据 使用 MySQLi 和 PDO 向 MySQL 插入多条数据 mysqli_multi_query() 函数可用来执行多条SQL语句. 以下实例向 "MyG ...

  4. PHP strstr() 函数

    实例 查找 "world" 在 "Hello world!" 中是否存在,如果是,返回该字符串及后面剩余部分: <?php echo strstr(&qu ...

  5. luogu 2478 [SDOI2010]城市规划 仙人掌上dp.

    LINK:城市规划 以前ls 让写的时候由于看不懂题目+以为在图中的环上dp非常困难所以放弃治疗了. 现在终于能把题目看懂了 泪目... 题目其实就是在说 给出一张图这个有一个非常好的性质 满足每个点 ...

  6. luogu P6125 [JSOI2009]有趣的游戏

    LINK:有趣的游戏 直接说做法了.首先是 我是不会告诉你我看完题后不太会 摸了2h鱼后看题解 一直翻发现自己题目有些没读完整.. 题目中说了每个字符串长度相同 而我一直在思考AC自动机可能存在一些节 ...

  7. 详细记录了python爬取小说《元尊》的整个过程,看了你必会~

    学了好几天的渗透测试基础理论,周末了让自己放松一下,最近听说天蚕土豆有一本新小说,叫做<元尊>,学生时代的我可是十分喜欢读天蚕土豆的小说,<斗破苍穹>相信很多小伙伴都看过吧.今 ...

  8. 041_go语言中的panic

    代码演示: package main import "os" func main() { // panic("a problem") _, err := os. ...

  9. zuul路由网关集成ssl,实现http到https的转变

    1 前言 最近几天刚开始接触微信小程序的开发,才接触到了https的概念(微信小程序中的请求必须为https请求,不然请求无法成功).https算是对http的安全封装,在http的基础上加了ssl证 ...

  10. 网络协议: TCP/IP 和UDP/IP

    网络协议: TCP/IP 和UDP/IP TCP/IP TCP/IP(Transmission Control Protocol/Internet Protocol)是一种可靠的网络数据传输控制协议. ...