- 背景
- 一、整体方案
- 二、AOP
- 1.反射解析属性
- 2.SpEL解析属性
- 3.下载接口
- 4.预览接口
- 总结
背景
最近工作上在做安全管控的需求,需要限制一些接口的调用次数,一般可以采用两种方案,一种是将在后端使用AOP进行限制,另外一种是在后端开一个http接口,前端每次调用的时候,先调用安全管控的接口,接口返回成功的情况下,才进行实际业务操作。本文主要总结使用AOP限制次数踩的一些坑
一、整体方案
整体方案如上图所示,使用AOP技术,在原有的基础上,增加规则判断。
getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
同样类似的还有getConstructors()和getDeclaredConstructors()、getMethods()和getDeclaredMethods(),这两者分别表示获取某个类的方法、构造函数。
private Object parseFieldValue(JoinPoint jp, String filed){
Signature signature = jp.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
Object[] args = jp.getArgs();
String[] parameterNames = methodSignature.getParameterNames();
Class[] parameterTypes = method.getParameterTypes();
String[] filedNames = filed.split("\.");
for (int i = 0; i < parameterNames.length; i++){
if (!parameterNames[i].equals(filedNames[0])){
continue;
}
if (filedNames.length == 1){
return args[i];
}
try{
return parseFiled(parameterTypes[i], args[i], filedNames, 1);
} catch (IllegalAccessException e1){
e1.printStackTrace();
}
}
throw new IllegalArgumentException("解析field失败");
}
private Object parseFiled(Class> parameterType, Object targetObject, String[] filedNames, int index) throws IllegalAccessException{
try{
Field field = parameterType.getDeclaredField(filedNames[index]);
field.setAccessible(true);
Object result = field.get(targetObject);
if (filedNames.length == index){
return result;
} else {
return parseFiled(result.getClass(), result, filedNames, ++index);
}
} catch (NoSuchFieldException e) {
return parseFiled(parameterType.getSuperclass(), targetObject, filedNames, index);
}
}
2.SpEL解析属性
private3.下载接口T parseSpel(ProceedingJoinPoint jp, String spel, Class clazz, T defaultResult) { expressionParser parser = new SpelexpressionParser(); Signature signature = jp.getSignature(); MethodSignature methodSignature = null; if (signature instanceof MethodSignature){ methodSignature = (MethodSignature) signature; } if (methodSignature == null){ return defaultResult; } Method method = methodSignature.getMethod(); String[] params = methodSignature.getParameterNames(); Object[] arguments = jp.getArgs(); evaluationContext context = new StandardevaluationContext(); for (int len = 0; len < params.length; len++) { context.setVariable(params[len], arguments[len]); } try { expression expression = parser.parseexpression(spel); return expression.getValue(context, clazz); } catch (Exception e) { return defaultResult; } }
附件下载的时候,由于下载直接是浏览器控制,所以返回特定的错误,或者返回null,对于用户的提示效果都不太好。可以通过页面跳转到固定的错误页面,或者直接html的方式进行解决。
4.预览接口项目上面预览使用的viewer.js来做的,直接url绑定到img上面,所以这个根本上就没有好的方法给用户进行提示,只能在前端进行改造。
总结涉及前端到类似的方案评审的时候,需要拉上前端的同事,自己本来是前端小白,经验有限,临时改方案,增加自己的工作量,吃力不讨好。



