/**
* 修饰函数和参数,用于属性的核查
*
* <p>
* <ul>
* <li>1.修饰类:则会核查类下面所有函数的所有参数</li>
* <li>2.修饰函数:则会核查函数对应的所有参数</li>
* <li>3.修饰参数:则只会核查指定的参数</li>
* </ul>
* @author robot
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
public @interface AutoCheck {
/**
* 分组
*/
String group() default "_default_";
}
/**
* 添加该注解,则会在切面中,将修饰的方法的出参入参和耗时打印到info日志中
*
* @author robot
*/
@Documented
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableAopLog
{}
添加mikilin进行核查,也就是说跟这个结合
/**
* @author robot
*/
@Slf4j
@Aspect
@Component
public class ControllerAop {
/**
* 拦截方法中添加注解{@link EnableAopLog}的方法
*/
@Around("@annotation(com.isyscore.walle.admin.aop.EnableAopLog)")
public Object aroundEnableLog(ProceedingJoinPoint pjp) throws Throwable {
Method currentMethod = getMethod(pjp);
EnableAopLog enableAopLog = currentMethod.getDeclaredAnnotation(EnableAopLog.class);
long start = System.currentTimeMillis();
NeoMap outInfo = NeoMap.of();
// 函数名字
String funStr = pjp.getSignature().toLongString();
outInfo.put("fun", funStr);
// 参数的值
outInfo.put("parameters", getParameters(pjp));
Object result = null;
try {
result = pjp.proceed();
outInfo.put("result", result);
} catch (Exception e) {
outInfo.put("timeout", TimeRangeStrUtil.parseTime(System.currentTimeMillis() - start));
log.error(JSON.toJSONString(outInfo), e);
return result;
}
outInfo.put("timeout", TimeRangeStrUtil.parseTime(System.currentTimeMillis() - start));
if (enableAopLog.enable()) {
log.info(JSON.toJSONString(outInfo));
}
return result;
}
/**
* 拦截controller中所有的方法
*/
@Around("execution(* com.isyscore.walle.admin.web.controller.*.*(..))")
public Object aroundParameter(ProceedingJoinPoint pjp) {
long start = System.currentTimeMillis();
String funStr = pjp.getSignature().toLongString();
Object result;
Method currentMethod = getMethod(pjp);
try {
validate(pjp);
result = pjp.proceed();
} catch (Throwable e) {
NeoMap outInfo = NeoMap.of();
outInfo.put("fun", funStr);
outInfo.put("parameters", getParameters(pjp));
outInfo.put("timeout", TimeRangeStrUtil.parseTime(System.currentTimeMillis() - start));
outInfo.put("errMsg", e.getMessage());
log.error("后端异常:" + outInfo.toString(), e);
Class<?> returnClass = currentMethod.getReturnType();
if (e instanceof BusinessException) {
if (Response.class.isAssignableFrom(returnClass)) {
BusinessException businessException = (BusinessException) e;
return Response.fail(businessException.getErrCode(), businessException.getMessage());
} else {
return null;
}
} else {
if (Response.class.isAssignableFrom(returnClass)) {
return Response.fail(HttpStatus.INTERNAL_SERVER_ERROR.toString(), e.getMessage());
} else {
return null;
}
}
}
return result;
}
private List<Object> getParameters(ProceedingJoinPoint pjp) {
List<Object> parameters = new ArrayList<>();
Object[] args = pjp.getArgs();
for (Object arg : args) {
if (arg instanceof ServletRequest || arg instanceof ServletResponse || arg instanceof MultipartFile) {
continue;
}
parameters.add(arg);
}
return parameters;
}
@SuppressWarnings("all")
private void validate(ProceedingJoinPoint pjp) {
Signature sig = pjp.getSignature();
MethodSignature methodSignature;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
methodSignature = (MethodSignature) sig;
Method currentMethod;
try {
currentMethod = pjp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new BusinessException(e);
}
if (currentMethod.getDeclaringClass().isAnnotationPresent(AutoCheck.class)) {
doValidate(pjp);
} else if (currentMethod.isAnnotationPresent(AutoCheck.class)) {
doValidate(pjp);
} else {
Parameter[] parameters = currentMethod.getParameters();
Object[] args = pjp.getArgs();
for (int index = 0; index < args.length; index++) {
if (args[index] instanceof ServletRequest || args[index] instanceof ServletResponse || args[index] instanceof MultipartFile) {
continue;
}
if (parameters[index].isAnnotationPresent(AutoCheck.class)) {
try {
MkValidators.validate(args[index]);
} catch (MkCheckException e) {
throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.toString(), "参数核查异常:" + MkValidators.getErrMsg());
}
}
}
}
}
@SuppressWarnings("all")
private void doValidate(ProceedingJoinPoint pjp) {
Object[] parameters = pjp.getArgs();
for (Object parameter : parameters) {
try {
MkValidators.validate(parameter);
} catch (MkCheckException e) {
String checkErr = "参数核查异常:" + MkValidators.getErrMsg();
throw new BusinessException(HttpStatus.INTERNAL_SERVER_ERROR.toString(), checkErr);
}
}
}
private Method getMethod(ProceedingJoinPoint pjp) {
Signature sig = pjp.getSignature();
MethodSignature methodSignature;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}
methodSignature = (MethodSignature) sig;
Method currentMethod;
try {
currentMethod = pjp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new BusinessException(e);
}
return currentMethod;
}
}