jfinal js 拦截_jfinal 使用拦截器处理繁琐的前置条件判定
使用攔截器處理繁瑣的前置條件判定
背景
在開發過程中,為了提高程序的健壯性,對參數的校驗是必不可少的,然而使用傳統的方式進行參數校驗時,導致程序中存在了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 使用拦截器处理繁琐的前置条件判定的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 触发器和java的关系_触发器-1 -
- 下一篇: java重量级框架_框架之轻量级和重量级