-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
307 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/main/java/com/ecfront/dew/common/interceptor/DewInterceptExec.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/com/ecfront/dew/common/interceptor/DewInterceptRespBody.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|
||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/com/ecfront/dew/common/interceptor/DewInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) { | ||
|
||
} | ||
|
||
} |
100 changes: 100 additions & 0 deletions
100
src/main/java/com/ecfront/dew/common/interceptor/DewInterceptorProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
108
src/test/java/com/ecfront/dew/common/InterceptorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} | ||
} | ||
|
||
|
||
} |