在业务的实现过程中,尤其是对外接口开发,我们需要对请求进行大量的验证并返回错误状态码和描述。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. nginx里的变量,实现简单过滤。

    1,nginx内置变量 nginx 有很多内置变量可以进行简单的过滤. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ...

  2. HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第5章CSS盒子模型

    本教程案例在线演示 有路网PC端 有路网移动端 教程配套源码资源 教程配套源码资源 div div 可定义文档中的分区(division). div 标签可以把网页分割为独立的.不同的部分. 可以看成 ...

  3. PHP开发者该知道的多进程消费队列

    引言 最近开发一个小功能,用到了队列mcq,启动一个进程消费队列数据,后边发现一个进程处理不过来了,又加了一个进程,过了段时间又处理不过来了… 这种方式每次都要修改crontab,如果进程挂掉了,不会 ...

  4. [转]Nginx介绍-反向代理、负载均衡

    原文:https://www.cnblogs.com/wcwnina/p/8728391.html 作者:失恋的蔷薇 1. Nginx的产生 没有听过Nginx?那么一定听过它的"同行&qu ...

  5. 我靠!Semaphore里面居然有这么一个大坑!

    这是why的第 59 篇原创文章 荒腔走板 大家好,我是why哥 ,欢迎来到我连续周更优质原创文章的第 59 篇. 上周写了一篇文章,一不小心戳到了大家的爽点,其中一个转载我文章的大号,阅读量居然突破 ...

  6. 【FZYZOJ】无向图的联通图个数 题解(组合数学)

    题目大意:求无向图的连通图个数.由于个数可能很大,只需要求出结果$mod1000000009$的值.$n\leq 1000$ ------------------------- 对于一个含有$n$个结 ...

  7. CF1349F 【Slime and Sequences】part1

    由于本文过长,\(\LaTeX\) 炸了,分两篇,part2 题目描述 定义一个正整数序列为好序列,当且仅当如果某个数 \(k\) 出现过,那么一定有 \(k-1\) 在最后一个 \(k\) 的前面出 ...

  8. 畅购商城(八):微服务网关和JWT令牌

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 畅购商城(一):环境搭建 畅购商 ...

  9. JavaScript 模块封装

    JavaScript 模块封装 前言介绍 在最早的时候JavaScript这门语言其实是并没有模块这一概念,但是随着时间的推移与技术的发展将一些复用性较强的代码封装成模块变成了必要的趋势. 在这篇文章 ...

  10. Springboot日志LOGO改变和设计

    每次启动Springboot的时候,SpringBoot都会打印一个LOGO,那么这个LOGO是可以关闭和改变的. 1.关闭Springboot的LOGO 2.改变Springboot的日志LOGO ...