Skip to content

Commit

Permalink
Add common interceptor
Browse files Browse the repository at this point in the history
  • Loading branch information
gudaoxuri committed Apr 11, 2017
1 parent 1fa6f8e commit 7f2b450
Show file tree
Hide file tree
Showing 7 changed files with 307 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Dew公共模块
1. 定时器(TimerHelper)
1. 常用时间处理(TimeHelper)
1. 主流文件MIME整理(MimeHelper)
1. 通用拦截器栈(DewInterceptorProcessor)

### 使用

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.compilerVersion>${java.version}</maven.compiler.compilerVersion>
<jackson.version>2.8.6</jackson.version>
<jackson.version>2.8.7</jackson.version>
<beanutils.version>1.9.3</beanutils.version>
<jbcrypt.version>0.3m</jbcrypt.version>
<slf4j.version>1.7.22</slf4j.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.ecfront.dew.common.interceptor;

import com.ecfront.dew.common.Resp;

import java.util.Map;

@FunctionalInterface
public interface DewInterceptExec<E> {

Resp<DewInterceptRespBody<E>> exec(E obj, Map<String, Object> context);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.ecfront.dew.common.interceptor;

import java.util.Map;

public class DewInterceptRespBody<E> {

private E obj;
private Map<String, Object> context;

public static <E> DewInterceptRespBody<E> build(E obj, Map<String, Object> context) {
DewInterceptRespBody<E> body = new DewInterceptRespBody<>();
body.setObj(obj);
body.setContext(context);
return body;
}

public E getObj() {
return obj;
}

public void setObj(E obj) {
this.obj = obj;
}

public Map<String, Object> getContext() {
return context;
}

public void setContext(Map<String, Object> context) {
this.context = context;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.ecfront.dew.common.interceptor;

import com.ecfront.dew.common.Resp;

import java.util.Map;

/**
* 拦截器栈定义
*
* @param <E> 对象的类型
*/
public interface DewInterceptor<E> {

/**
* 获取拦截器所属类型,用于区别不同的栈
*/
String getCategory();

/**
* 获取拦截器名称
*/
String getName();

/**
* 前置执行
*
* @param obj 对象
* @param context 参数
* @return 执行后结果
*/
Resp<DewInterceptRespBody<E>> before(E obj, Map<String, Object> context);

/**
* 后置执行
*
* @param obj 对象
* @param context 参数
* @return 执行后结果
*/
Resp<DewInterceptRespBody<E>> after(E obj, Map<String, Object> context);

/**
* 错误处理,在前置/后置执行错误时触发,多用于资源回收
*
* @param obj 对象
* @param context 参数
*/
default void error(E obj, Map<String, Object> context) {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.ecfront.dew.common.interceptor;

import com.ecfront.dew.common.Resp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 拦截器栈执行器
*/
public class DewInterceptorProcessor {

private static Logger logger = LoggerFactory.getLogger(DewInterceptorProcessor.class);

private static Map<String, List<DewInterceptor<?>>> CONTAINER = new HashMap<>();

/**
* 注册拦截器栈
*
* @param category 拦截类型
* @param interceptor 拦截器
*/
public static void register(String category, DewInterceptor<?> interceptor) {
if (!CONTAINER.containsKey(category)) {
CONTAINER.put(category, new ArrayList<>());
}
CONTAINER.get(category).add(interceptor);
}

/**
* 注册拦截器栈
*
* @param category 拦截类型
* @param interceptors 拦截器列表
*/
public static void register(String category, List<DewInterceptor<?>> interceptors) {
CONTAINER.put(category, interceptors);
}

/**
* 拦截器栈处理方法
*
* @param category 拦截类型
* @param obj 初始入栈对象
* @param context 初始入栈参数
* @param fun 实际执行方法
* @tparam E 对象的类型
*/
public static <E> Resp<DewInterceptRespBody<E>> process(String category, E obj, Map<String, Object> context, DewInterceptExec<E> fun) {
logger.debug("[DewInterceptorProcessor] Process [{}]", category);
if (!CONTAINER.containsKey(category)) {
return fun.exec(obj, context);
}
List<DewInterceptor<?>> interceptors = CONTAINER.get(category);
Resp<DewInterceptRespBody<E>> beforeR = doProcess(obj, context, interceptors, true);
if (!beforeR.ok()) {
return beforeR;
}
Resp<DewInterceptRespBody<E>> execR = fun.exec(beforeR.getBody().getObj(), beforeR.getBody().getContext());
if (!execR.ok()) {
return execR;
}
return doProcess(obj, context, interceptors, false);
}

private static <E> Resp<DewInterceptRespBody<E>> doProcess(E obj, Map<String, Object> context, List<DewInterceptor<?>> interceptors, boolean isBefore) {
Resp<DewInterceptRespBody<E>> result = Resp.success(DewInterceptRespBody.build(obj, context));
for (DewInterceptor<?> interceptor : interceptors) {
logger.trace("[DewInterceptorProcessor] Process interceptor [{}]:{}-{}", interceptor.getCategory(), interceptor.getName(), isBefore ? "before" : "after");
E preObj = result.getBody().getObj();
Map<String, Object> preContext = result.getBody().getContext();
DewInterceptor<E> interceptorE = (DewInterceptor<E>) interceptor;
try {
if (isBefore) {
result = interceptorE.before(preObj, preContext);
} else {
result = interceptorE.after(preObj, preContext);
}
if (!result.ok()) {
logger.warn("[DewInterceptorProcessor] Process interceptor error [{}]:{}-{},[{}]{}",
interceptor.getCategory(), interceptor.getName(), isBefore ? "before" : "after", result.getCode(), result.getMessage());
interceptorE.error(preObj, preContext);
return result;
}
} catch (Throwable e) {
result = Resp.serverError(e.getMessage());
logger.error("[DewInterceptorProcessor] Process interceptor error [{}]:{}-{},[{}]{}",
interceptor.getCategory(), interceptor.getName(), isBefore ? "before" : "after", result.getCode(), result.getMessage());
interceptorE.error(preObj, preContext);
return result;
}
}
return result;
}

}
108 changes: 108 additions & 0 deletions src/test/java/com/ecfront/dew/common/InterceptorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.ecfront.dew.common;

import com.ecfront.dew.common.interceptor.DewInterceptRespBody;
import com.ecfront.dew.common.interceptor.DewInterceptor;
import com.ecfront.dew.common.interceptor.DewInterceptorProcessor;
import org.junit.Assert;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class InterceptorTest {

@Test
public void testInterceptor() throws Exception {
// none
Resp<DewInterceptRespBody<Obj>> resp = DewInterceptorProcessor.process("none", new Obj("1"), new HashMap<>(), (obj, context) ->
Resp.success(DewInterceptRespBody.build(obj, context))
);
Assert.assertTrue(resp.ok());
Assert.assertEquals("1", resp.getBody().getObj().getF());
// has one
DewInterceptorProcessor.register("test",new InterceptorA());
resp = DewInterceptorProcessor.process("test", new Obj("1"), new HashMap<>(), (obj, context) ->
Resp.success(DewInterceptRespBody.build(obj, context))
);
Assert.assertTrue(resp.ok());
Assert.assertEquals("3", resp.getBody().getObj().getF());
// error
DewInterceptorProcessor.register("test",new InterceptorB());
resp = DewInterceptorProcessor.process("test", new Obj("1"), new HashMap<>(), (obj, context) ->
Resp.success(DewInterceptRespBody.build(obj, context))
);
Assert.assertTrue(!resp.ok());
}


public class Obj {
private String f;

public Obj(String f) {
this.f = f;
}

public String getF() {
return f;
}

public void setF(String f) {
this.f = f;
}
}

public class InterceptorA implements DewInterceptor<Obj> {

@Override
public String getCategory() {
return "test";
}

@Override
public String getName() {
return "A";
}

@Override
public Resp<DewInterceptRespBody<Obj>> after(Obj obj, Map context) {
obj.setF("3");
return Resp.success(DewInterceptRespBody.build(obj,context));
}

@Override
public Resp<DewInterceptRespBody<Obj>> before(Obj obj, Map context) {
obj.setF("2");
return Resp.success(DewInterceptRespBody.build(obj, context));
}
}

public class InterceptorB implements DewInterceptor<Obj> {

@Override
public String getCategory() {
return "test";
}

@Override
public String getName() {
return "B";
}

@Override
public Resp<DewInterceptRespBody<Obj>> after(Obj obj, Map context) {
return Resp.success(DewInterceptRespBody.build(obj,context));
}

@Override
public Resp<DewInterceptRespBody<Obj>> before(Obj obj, Map context) {
return Resp.badRequest("some error");
}

@Override
public void error(Obj obj, Map<String, Object> context) {
obj.setF("error");
}
}


}

0 comments on commit 7f2b450

Please sign in to comment.