使用拦截器处理繁琐的前置条件判定

背景

在开发过程中,为了提高程序的健壮性,对参数的校验是必不可少的,然而使用传统的方式进行参数校验时,导致程序中存在了if xxx return xxx;处理不够优雅。虽然jfinal提供了Validator,但是使用过于繁琐,对前后端分离不友好。 在guaua工具包中的Preconditions启发下,本人利用拦截器和自定义异常实现了一个较为优雅的参数校验方法。(注:未经全面测试,仅供参考)

正文(直接上代码)

ParaExceptionInterceptor 自定义异常拦截器(仅拦截返回值为Ret的方法)

public class ParaExceptionInterceptor implements Interceptor {

@SuppressWarnings("unchecked")

private static final List> DEFAULT_EXCPTIONS = Lists.newArrayList(ParaExcetion.class);

private static List> getConfigWithExceptionConfig(Invocation inv) {

ExceptionConfig config = inv.getMethod().getAnnotation(ExceptionConfig.class);

if (config == null)

config = inv.getTarget().getClass().getAnnotation(ExceptionConfig.class);

if (config != null) {

Class extends Exception>[] value = config.value();

return Arrays.asList(value);

}

return DEFAULT_EXCPTIONS;

}

/**

* (non-Javadoc)

* Title: intercept

* Description:对指定异常进行拦截并封装为错误信息返回

* @param inv

* @see com.jfinal.aop.Interceptor#intercept(com.jfinal.aop.Invocation)

*/

@Override

public void intercept(Invocation inv) {

try {

inv.invoke();

} catch (Exception e) {

// 若返回值类型不是Ret则将异常继续往上抛

Class> returnType = inv.getMethod().getReturnType();

if (!(returnType.equals(Ret.class))) {

throw e;

}

List> exceptionClasses = getConfigWithExceptionConfig(inv);

for (Class extends Exception> exceptionClass : exceptionClasses) {

if (Objects.equals(e.getClass(), exceptionClass) || Objects.equals(e.getClass().getSuperclass(), exceptionClass)) {

inv.setReturnValue(MRetKit.buildFail(e.getMessage()));

return;

}

}

throw e;

}

}

}

ParaExcetion 自定义异常

public class ParaExcetion extends com.iipcloud.api.exception.ParaExcetion {

/** serialVersionUID */

private static final long serialVersionUID = 4888200095167386189L;

/**

*

Title:

*

Description:

*/

public ParaExcetion() {

super();

}

/**

*

Title:

*

Description:

* @param message

* @param cause

* @param enableSuppression

* @param writableStackTrace

*/

public ParaExcetion(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {

super(message, cause, enableSuppression, writableStackTrace);

}

/**

*

Title:

*

Description:

* @param message

* @param cause

*/

public ParaExcetion(String message, Throwable cause) {

super(message, cause);

}

/**

*

Title:

*

Description:

* @param message

*/

public ParaExcetion(String message) {

super(message);

}

/**

*

Title:

*

Description:

* @param cause

*/

public ParaExcetion(Throwable cause) {

super(cause);

}

}

ExceptionConfig 异常注解

@Retention(RUNTIME)

@Target({ TYPE, METHOD })

public @interface ExceptionConfig {

Class extends Exception>[] value();

}

ParaCheckKit 配套工具类

public class ParaCheckKit {

private ParaCheckKit() {

super();

}

public static void requireFalse(boolean expression, String errMsgFormat, Object... args) {

requireTrue(!expression, String.format(errMsgFormat, args));

}

/**

* Title: checkPara

* Description: 检查表达式是否满足,若不满足则抛出异常

* Date: 2020年2月25日

* @param expression

* @param errMsg

* @throws IllegalParaException

*/

public static void requireTrue(boolean expression, String errMsg) {

if (!expression) {

throw new IllegalParaException(errMsg);

}

}

public static void requireTrue(boolean expression, String errMsgFormat, Object... args) {

if (!expression) {

throw new IllegalParaException(String.format(errMsgFormat, args));

}

}

/**

* Title: requireNotNull

* Description: 判断指定对象是否为空,为空则抛出异常

* Date: 2020年2月25日

* @param obj

* @param errMsg

* @throws IllegalParaException

*/

public static void requireNotNull(Object obj, String errMsg, Object... args) {

requireTrue(Objects.nonNull(obj), errMsg, args);

}

public static void requireNull(Object obj, String errMsg, Object... args) {

requireTrue(Objects.isNull(obj), errMsg, args);

}

/**

* Title: requireNotBlank

* Description:判断指定字符串是否为空,为空则抛出异常

* Date: 2020年2月25日

* @param str

* @param errMsg

* @throws com.iipmes.exception.IllegalParaException

*/

public static void requireNotBlank(String str, String errMsg, Object... args) {

requireTrue(StrKit.notBlank(str), errMsg, args);

}

public static void requireBlank(String str, String errMsg, Object... args) {

requireTrue(StrKit.isBlank(str), errMsg, args);

}

/**

* Title: requireNotEmpty

* Description:

* Date: 2020年2月25日

* @param obj

* @param errMsg

* @throws com.iipmes.exception.IllegalParaException

*/

public static void requireNotEmpty(Object obj, String errMsg, Object... args) {

requireTrue(IIPUtil.notEmpty(obj), errMsg, args);

}

public static void requireEmpty(Object obj, String errMsg, Object... args) {

requireTrue(IIPUtil.isEmpty(obj), errMsg, args);

}

/**

* Title: checkModel

* Description: 检查model中的指定字段是否为空,为空则抛出异常

* Date: 2020年2月25日

* @param model

* @param fields

*/

public static void checkModel(Model extends Model>> model, List fields, String errMsg, Object... args) {

requireTrue(fieldNotEmpty(model, fields), errMsg, args);

}

public static boolean fieldNotEmpty(Model extends Model>> model, String... fields) {

return fieldNotEmpty(model, Arrays.asList(fields));

}

/**

* Title: fieldNotEmpty

* Description: 检查Model中指定的字段

* Date: 2020年2月25日

* @param model

* @param fields

* @return

*/

public static boolean fieldNotEmpty(Model extends Model>> model, List fields) {

for (String field : fields) {

if (ObjectKit.isEmpty(model.get(field))) {

return false;

}

}

return true;

}

}

使用demo

@Before(ParaExceptionInterceptor.class)

public class DemoService {

public Ret doSomeThing(Record record, Model extends Model>> model) {

ParaCheckKit.requireNotNull(record.getStr("id"), "id can not be null");

ParaCheckKit.checkModel(model, Lists.newArrayList("id,name"), "id required, name required");

// do Something

return Ret.ok();

}

}

注意事项

配合静态方法导入更为舒爽

1.jpg

以上提供的只是一个简单的demo,适用于servce层,Controller层使用需要改动(默认无返回值,可自定义一个拦截器处理返回值返回给前端页面,下面是一个简单示例)。

public class ActionInterceptor implements Interceptor {

/**

* (non-Javadoc)

*

Title: intercept

*

Description:

* @param inv

* @see com.jfinal.aop.Interceptor#intercept(com.jfinal.aop.Invocation)

*/

@Override

public void intercept(Invocation inv) {

inv.invoke();

Class> returnType = inv.getMethod().getReturnType();

if (returnType.equals(Void.class)) {

return;

}

Object returnValue = inv.getReturnValue();

if (returnType.equals(String.class)) {

inv.getController().render((String) returnValue);

} else if (returnType.equals(Ret.class)) {

inv.getController().renderJson((Ret) returnValue);

} else {

inv.getController().renderJson(RetKit.buildOk(returnValue));

}

}

}

jfinal js 拦截_jfinal 使用拦截器处理繁琐的前置条件判定相关推荐

  1. Node.js与Sails~方法拦截器policies

    policies sails的方法拦截器类似于.net mvc里的Filter,即它可以作用在controller的action上,在服务器响应指定action之前,对这个action进行拦截,先执行 ...

  2. springboot拦截器拦截提示_Springboot拦截器使用及其底层源码剖析

    博主最近看了一下公司刚刚开发的微服务,准备入手从基本的过滤器以及拦截器开始剖析,以及在帮同学们分析一下上次的jetty过滤器源码与本次Springboot中tomcat中过滤器的区别.正题开始,拦截器 ...

  3. axios请求拦截和响应拦截

    在我们平常调用接口的时候,会使用到拦截器这个工具,大致有两种用法,请求拦截和响应拦截. 请求拦截 axios.interceptors.request.use((config)=>{return ...

  4. axios的请求拦截和响应拦截

    1.安装axios npm install axios --save 2.引入模块 在untils文件夹中创建request.js文件,引入axios模块 import axios from &quo ...

  5. 【Android 逆向】函数拦截实例 ( 函数拦截流程 | ① 定位动态库及函数位置 )

    文章目录 一.函数拦截流程 二.定位动态库及函数位置 一.函数拦截流程 函数拦截流程 : 定位动态库及函数位置 : 获取该动态库在内存中的位置 , 以便于 查找函数位置 ; 插桩 : 在函数的入口处插 ...

  6. 【Android 逆向】函数拦截 ( GOT 表拦截 与 插桩拦截 | 插桩拦截简介 | 插桩拦截涉及的 ARM 和 x86 中的跳转指令 )

    文章目录 一.GOT 表拦截与插桩拦截 二.插桩拦截简介 三.插桩拦截涉及的 ARM 和 x86 中的跳转指令 一.GOT 表拦截与插桩拦截 函数拦截有 222 种方式 : 使用 GOT 表进行函数拦 ...

  7. 电话拦截以及电话拦截后的提示音

    1. 电话拦截 这个功能大家可能都知道了,就是利用反射原理调用ITelephony的隐藏方法来实现.这个就不说了,在附件的代码里有. 2.拦截后提示忙音/空号/已关机/已停机 这个功能其实是要用到MM ...

  8. 在HarmonyOS中实现基于JS卡片的音乐播放器

    /   今日科技快讯   / 近日,苹果首席执行官蒂姆·库克接受<时代>杂志专访,谈及他本人对领导力.企业价值和新技术的看法.库克表示,苹果不仅要引领创新,还要努力让世界变得更安全更公平, ...

  9. Js简单实现音乐播放器

    Js简单实现音乐播放器 HTML部分 CSS部分 js代码部分 这段时间正好是寒假,闲来无事把大二学的web再温习了一遍,在学习到Js时,想找一些小玩意来练练手,于是我就用原生Js做了一个简单音乐播放 ...

最新文章

  1. 微信小程序获取text的值与获取input的输入的值
  2. iOS从零开始学习直播之2.采集
  3. Java数据结构类如何使用_Matlab如何使用Java的数据结构类型
  4. 004_JDK的String类对Comparable接口的实现
  5. Day 20: 斯坦福CoreNLP —— 用Java给Twitter进行情感分析
  6. 深度学习(神经网络)[1]——单层感知器
  7. 总分 Score Inflation
  8. centos 安装 图像识别工具 tesseract-ocr 流程
  9. 史上最复杂业务场景,逼出阿里高可用三大法宝
  10. vb添加GIF动态图片
  11. 当子元素用position:relative;时,父元素的overflow:hidden;在ie中失效的解决办法
  12. 用CMake编译lua
  13. [SAP ABAP开发技术总结]选择屏幕——各种屏幕元素演示
  14. 178.16. cvs release
  15. 常见的两种解空间 全排列与幂集
  16. 从“H1N1病毒”看危机意识的重要性
  17. 推荐系统领域最新研究进展论文整理
  18. Win8.1 取消开机密码
  19. mysql系列之复制2----主从同步部署
  20. Android Zxing集成

热门文章

  1. js联动清除的一个想法
  2. struts2 实现多文件限制上传
  3. 对付网络盗贼的三板斧
  4. css3学习 之 css选择器(结构性伪类选择器)
  5. TextView图文混排,显示添加的图片,三种常用方法,亲测
  6. 浅谈redis数据库的键值设计
  7. linux的同步与互斥
  8. 无缓冲channel
  9. 静态链接库与动态链接库的优缺点
  10. springmvc二十一:自定义类型转换器