在业务的实现过程中,尤其是对外接口开发,我们需要对请求进行大量的验证并返回错误状态码和描述。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") 获取当前序列化输出,可用于统一的业务日志记录

最新文章

  1. vi使用
  2. Solr搭建大数据查询平台
  3. android环境配置
  4. windows下在文件夹中快速启动cmd
  5. union联合体
  6. LeetCode:Search in Rotated Sorted Array I II
  7. 转载:看c++ primer 学习心得
  8. .Net学习难点讨论系列17 - 线程本地变量的使用
  9. @Data 注解引出的 lombok 小辣椒
  10. React Native网络请求
  11. java对excel操作
  12. JavaScript--序列化以及转义
  13. Andorid 翻书效果
  14. seo-摘自网友
  15. nginx信号量
  16. Ajax实现异步刷新验证用户名是否已存在
  17. 将linux上的Java代码上传到码云
  18. Loadrunner自带协议分析工具:Protocol Advisor
  19. Mysql 性能调优参数
  20. mui 怎样监听scroll事件的滚动距离

热门文章

  1. python自带函数
  2. 你不知道的JavaScript 上卷 2/11
  3. pandas_时间序列和常用操作
  4. 一款功能简约到可怜的SQL 客户端
  5. 在sharepoint 2010创建级联下拉菜单
  6. PHP krsort() 函数
  7. PHP cal_to_jd() 函数
  8. php getimagesize 函数 - 获取图像信息
  9. [SCOI2007]降雨量 线段树和区间最值(RMQ)问题
  10. linux之DNS主域,从域,缓存服务器的架设