package com.yanzuoguang.cloud.aop; import com.yanzuoguang.cloud.service.TokenServiceCall; import com.yanzuoguang.log.AspectLog; import com.yanzuoguang.log.LogInfoVo; import com.yanzuoguang.log.LogString; import com.yanzuoguang.token.TokenHelper; import com.yanzuoguang.util.exception.ExceptionHelper; import com.yanzuoguang.util.helper.JsonHelper; import com.yanzuoguang.util.helper.StringHelper; import com.yanzuoguang.util.helper.TypeHelper; import com.yanzuoguang.util.helper.UrlHelper; import com.yanzuoguang.util.log.Log; import com.yanzuoguang.util.vo.CloudConfig; import com.yanzuoguang.util.vo.ResponseResult; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Optional; /** * 接口请求日志切面 * * @author 颜佐光 */ @Aspect @Component public class AspectWeb { private static final String TAG = AspectWeb.class.getSimpleName(); private final TokenServiceCall tokenServiceCall; private final WebAspectInit webAspectInit; private final CloudConfig cloudConfig; private final AspectLogUrl aspectLogUrl; private final AspectLogBody aspectLogBody; private final AspectLog aspectLog; private final LogString logString; public AspectWeb(TokenServiceCall tokenServiceCall, Optional<WebAspectInit> webAspectInit, CloudConfig cloudConfig, AspectLogUrl aspectLogUrl, AspectLogBody aspectLogBody, AspectLog aspectLog, LogString logString) { this.tokenServiceCall = tokenServiceCall; this.cloudConfig = cloudConfig; this.aspectLogUrl = aspectLogUrl; this.aspectLogBody = aspectLogBody; this.aspectLog = aspectLog; this.logString = logString; if (webAspectInit.isPresent()) { this.webAspectInit = webAspectInit.get(); } else { this.webAspectInit = req -> { }; Log.error(AspectWeb.class, "请设置登录默认处理函数,实现 WebAspectInit 接口"); } } /** * exec aop point aspect */ @Pointcut("execution(* *..web..*Controller.*(..))") public void webAspect() { } /** * 执行环形切面 * * @param joinPoint 切面对象 * @return 切面结果 */ @Around(value = "webAspect()") public Object requestWebAround(ProceedingJoinPoint joinPoint) throws Throwable { Class<?> declaringType = joinPoint.getSignature().getDeclaringType(); AspectLogUrl.WebUrlInfo webMethodUrl = aspectLogUrl.getWebMethodBaseUrl(joinPoint); // 判断是否网关 boolean isGateWay = cloudConfig.isGateWay(); if (isGateWay) { try { // 网关不进行任何拦截处理 return executeMethod(joinPoint); } catch (Exception ex) { System.err.println("请求地址错误:" + webMethodUrl.getRequestUrl()); throw ex; } } boolean clear = aspectLog.requestLogInit(); Object requestBody = aspectLogBody.getRequestBody(joinPoint); String bodyStringFrom = logString.getBodyString(requestBody); String bodyString = StringHelper.compare(webMethodUrl.getRequestUrl(), webMethodUrl.getConfigUrl()) ? bodyStringFrom : String.format("地址:%s 内容:%s", webMethodUrl.getRequestUrl(), bodyStringFrom); LogInfoVo log = aspectLog.start(declaringType, TAG, UrlHelper.getPage(webMethodUrl.getConfigUrl()), bodyString, clear); Exception ex = null; boolean isInit = false; Object result = null; try { // 请求登录服务初始化 isInit = tokenServiceCall.tokenInit(); // 初始化请求参数 for (Object arg : joinPoint.getArgs()) { webAspectInit.init(arg); } result = executeMethod(joinPoint); return result; } catch (Exception e) { ex = e; result = ExceptionHelper.getError(e); Type returnType = getReturnType(joinPoint); Class<?> returnClass = TypeHelper.getClass(returnType); if (returnClass != null && TypeHelper.isClass(returnClass, ResponseResult.class)) { return result; } else if (TypeHelper.isSubType(returnType, ResponseResult.class)) { return JsonHelper.to(result, returnClass); } else { throw e; } } finally { // 登录服务最终处理 tokenServiceCall.tokenFinish(); // 登录服务已经初始化则删除登录日志 if (isInit) { TokenHelper.remove(); } aspectLog.result(log, result, ex); } } /** * 获取返回的值类型 * * @param joinPoint 执行方法 * @return 类型 */ private Type getReturnType(ProceedingJoinPoint joinPoint) { Method m = getMethod(joinPoint); return m.getAnnotatedReturnType().getType(); } /** * 获取返回的至类型 * * @param joinPoint 执行方法 * @return 方法 */ private Method getMethod(ProceedingJoinPoint joinPoint) { //获取返回值类型 Signature s = joinPoint.getSignature(); MethodSignature ms = (MethodSignature) s; return ms.getMethod(); } /** * 执行方法 * * @param joinPoint 需要执行的方法 * @return 返回结果 * @throws Throwable 异常信息 */ private Object executeMethod(ProceedingJoinPoint joinPoint) throws Throwable { return joinPoint.proceed(); } }