package com.ssi.aspect; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.ssi.constant.VehicleConstant; import com.ssi.constant.enums.Status; import com.ssi.exception.CustomizeException; import com.ssi.utils.RestTemplateUtil; import com.ssi.utils.ToolUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.authz.AuthorizationException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * 登录校验及接口耗时记录切面 */ @Aspect @Component public class LoginAspect { @Value("${login-check-url}") private String loginCheckUrl; @Value("${OperationLog-Url}") private String operationLogUrl; @Value("${ExceptionLog-Url}") private String exceptionLogUrl; private static Long time; private JSONObject operationLogParam = new JSONObject(); private final String POINT_CUT = "(execution(public * com.ssi.controller..*(..)) " + "|| execution(public * com.ssi.dcvp.DcvpController.*(..))) " + "&& !execution(public * com.ssi.controller.BigScreenController.*(..))" + "&& !execution(public * com.ssi.controller.VmsDebugAppController.*(..))" + "&& !execution(public * com.ssi.controller.platform.TelecontrolTakeOverController.*(..))" + "&& !execution(public * com.ssi.controller.platform.RtkLocationController.*(..))" + "&& !execution(public * com.ssi.controller.VmsVehicleController.getVehicleByLocation(..))" + "&& !execution(public * com.ssi.controller.VmsCranePadBindController.getCraneByMac(..))" + "&& !execution(public * com.ssi.controller.VmsTosOrdersController.getVehicleByPadMac(..))" + "&& !execution(public * com.ssi.controller.VmsTosOrdersController.*(..))" + "&& !execution(public * com.ssi.controller.VmsChargingPileController.list(..))" + "&& !execution(public * com.ssi.controller.VmsRoadDeviceController.list(..))" + "&& !execution(public * com.ssi.controller.VmsAreaPositionController.list(..))" + "&& !execution(public * com.ssi.controller.VmsTerminalController.videoMonitor(..))" + "&& !execution(public * com.ssi.controller.CraneInfoController.queryCraneList(..))" + "&& !execution(public * com.ssi.controller.VmsRoadDeviceController.videoPlayUrlList(..))" + "&& !execution(public * com.ssi.controller.VmsCarControlCommandController.emergency(..))" + "&& !execution(public * com.ssi.controller.VmsCarControlCommandController.stepping(..))" + "&& !execution(public * com.ssi.controller.VmsTerminalController.videoMonitor(..))" + "&& execution(public * com.ssi.controller.VmsShipsDrawingController.saveShipTx(..))" + "&& !execution(public * com.ssi.dcvp.DcvpController.login(..))"; /** * 定义切入点,切入点为com.example.demo.aop.AopController中的所有函数 通过@Pointcut注解声明频繁使用的切点表达式 */ @Pointcut(POINT_CUT) public void LoginAspect() { } /** * 定义在方法执行前和执行后要增加执行的逻辑,登录校验和接口耗时记录 */ @Around("LoginAspect()") public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { long startTime = System.currentTimeMillis(); //获取token ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String token = getRequestToken(request); // if (StringUtils.isBlank(token)) { // throw new AuthorizationException(); // } String result = RestTemplateUtil.get(loginCheckUrl, token); JSONObject resultObj = JSONObject.parseObject(result); if ((int) resultObj.get("code") == Status.SUCCESS.getCode()) { request.getSession() .setAttribute(VehicleConstant.LOGIN_USER_KEY, resultObj.getJSONObject("data")); //接口调用开始时间 Object proceed = proceedingJoinPoint.proceed(); //接口调用花费时间 time = System.currentTimeMillis() - startTime; return proceed; } else if ((int) resultObj.get("code") == Status.UNAUTHORIZED.getCode()) { throw new AuthorizationException(); } else { throw new CustomizeException("登录异常,请重新登录"); } } /** * 获取请求的token */ private String getRequestToken(HttpServletRequest httpRequest) { //从header中获取token String token = httpRequest.getHeader("Authorization"); //如果header中不存在token,则从参数中获取token if (org.apache.commons.lang.StringUtils.isBlank(token)) { token = httpRequest.getParameter("Authorization"); } return token; } /** * 方法调用前,记录调用记录日志 */ @Before(value = "LoginAspect()") public void before(JoinPoint joinPoint) throws Exception { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); Object[] args = joinPoint.getArgs(); Collection collection = selectArgs(args); Map map = new HashMap(); map.put("operation", joinPoint.getSignature().getName()); map.put("content", new Gson().toJson(collection).toString()); map.put("type", request.getMethod()); map.put("url", request.getRequestURI().toString()); map.put("time", time); map.put("userAgent", request.getHeader("User-Agent")); String token = getRequestToken(request); operationLogParam.put("param", map); operationLogParam.put("token", token); } /** * 方法返回,插入操作日志 */ @AfterReturning(value = "LoginAspect()") public void afterReturning() throws Exception { Map param = operationLogParam.getObject("param", Map.class); param.put("time", time); RestTemplateUtil.post(operationLogUrl, JSONObject.toJSON(param).toString(), operationLogParam.getString("token")); } /** * 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行 * * @param joinPoint 切入点 * @param e 异常信息 */ @AfterThrowing(pointcut = "LoginAspect()", throwing = "e") public void afterThrowing(JoinPoint joinPoint, Throwable e) throws Exception { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); Map map = new HashMap(); Object[] args = joinPoint.getArgs(); Collection collection = selectArgs(args); map.put("oContent", new Gson().toJson(collection).toString()); map.put("type", request.getMethod()); map.put("url", request.getRequestURI().toString()); map.put("eContent", ToolUtils.stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace())); map.put("userAgent", request.getHeader("User-Agent")); String token = getRequestToken(request); RestTemplateUtil.post(exceptionLogUrl, JSONObject.toJSON(map).toString(), token); } private Collection selectArgs(Object[] args) { Collection collection = null; if (args.length > 0) { collection = CollectionUtils.select(Arrays.asList(args), object -> !(object instanceof ServletResponse) && !(object instanceof ServletRequest)); } return collection; } }