|  |  |  | 
|---|
|  |  |  | import java.util.Map; | 
|---|
|  |  |  | import javax.servlet.http.HttpServletRequest; | 
|---|
|  |  |  | import javax.servlet.http.HttpServletResponse; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import org.aspectj.lang.JoinPoint; | 
|---|
|  |  |  | import org.aspectj.lang.annotation.AfterReturning; | 
|---|
|  |  |  | import org.aspectj.lang.annotation.AfterThrowing; | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 操作日志记录处理 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @author ruoyi | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Aspect | 
|---|
|  |  |  | @Component | 
|---|
|  |  |  | public class LogAspect | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public class LogAspect { | 
|---|
|  |  |  | private static final Logger log = LoggerFactory.getLogger(LogAspect.class); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** 排除敏感属性字段 */ | 
|---|
|  |  |  | public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" }; | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 排除敏感属性字段 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"}; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 处理完请求后执行 | 
|---|
|  |  |  | 
|---|
|  |  |  | * @param joinPoint 切点 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") | 
|---|
|  |  |  | public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) { | 
|---|
|  |  |  | handleLog(joinPoint, controllerLog, null, jsonResult); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 拦截异常操作 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param joinPoint 切点 | 
|---|
|  |  |  | * @param e 异常 | 
|---|
|  |  |  | * @param e         异常 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") | 
|---|
|  |  |  | public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) { | 
|---|
|  |  |  | handleLog(joinPoint, controllerLog, e, null); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | try | 
|---|
|  |  |  | { | 
|---|
|  |  |  | protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | // 获取当前的用户 | 
|---|
|  |  |  | LoginUser loginUser = SecurityUtils.getLoginUser(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); | 
|---|
|  |  |  | operLog.setOperIp(ip); | 
|---|
|  |  |  | operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); | 
|---|
|  |  |  | if (loginUser != null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (loginUser != null) { | 
|---|
|  |  |  | operLog.setOperName(loginUser.getUsername()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (e != null) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (e != null) { | 
|---|
|  |  |  | operLog.setStatus(BusinessStatus.FAIL.ordinal()); | 
|---|
|  |  |  | operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | // 处理设置注解上的参数 | 
|---|
|  |  |  | getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); | 
|---|
|  |  |  | //判断状态码 | 
|---|
|  |  |  | Map resultMap=(Map)jsonResult; | 
|---|
|  |  |  | if(resultMap.get("code").equals(500)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | operLog.setStatus(BusinessStatus.FAIL.ordinal()); | 
|---|
|  |  |  | Map resultMap = (Map) jsonResult; | 
|---|
|  |  |  | if (StringUtils.isNotNull(resultMap)) { | 
|---|
|  |  |  | if (resultMap.get("code").equals(500)) { | 
|---|
|  |  |  | operLog.setStatus(BusinessStatus.FAIL.ordinal()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // 保存数据库 | 
|---|
|  |  |  | AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | catch (Exception exp) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | } catch (Exception exp) { | 
|---|
|  |  |  | // 记录本地异常日志 | 
|---|
|  |  |  | log.error("异常信息:{}", exp.getMessage()); | 
|---|
|  |  |  | exp.printStackTrace(); | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取注解中对方法的描述信息 用于Controller层注解 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param log 日志 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param log     日志 | 
|---|
|  |  |  | * @param operLog 操作日志 | 
|---|
|  |  |  | * @throws Exception | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception { | 
|---|
|  |  |  | // 设置action动作 | 
|---|
|  |  |  | operLog.setBusinessType(log.businessType().ordinal()); | 
|---|
|  |  |  | // 设置标题 | 
|---|
|  |  |  | 
|---|
|  |  |  | // 设置操作人类别 | 
|---|
|  |  |  | operLog.setOperatorType(log.operatorType().ordinal()); | 
|---|
|  |  |  | // 是否需要保存request,参数和值 | 
|---|
|  |  |  | if (log.isSaveRequestData()) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (log.isSaveRequestData()) { | 
|---|
|  |  |  | // 获取参数的信息,传入到数据库中。 | 
|---|
|  |  |  | setRequestValue(joinPoint, operLog); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // 是否需要保存response,参数和值 | 
|---|
|  |  |  | if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) { | 
|---|
|  |  |  | operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取请求的参数,放到log中 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param operLog 操作日志 | 
|---|
|  |  |  | * @throws Exception 异常 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception | 
|---|
|  |  |  | { | 
|---|
|  |  |  | private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception { | 
|---|
|  |  |  | String requestMethod = operLog.getRequestMethod(); | 
|---|
|  |  |  | if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) { | 
|---|
|  |  |  | String params = argsArrayToString(joinPoint.getArgs()); | 
|---|
|  |  |  | operLog.setOperParam(StringUtils.substring(params, 0, 2000)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else | 
|---|
|  |  |  | { | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); | 
|---|
|  |  |  | operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter()), 0, 2000)); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 参数拼装 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private String argsArrayToString(Object[] paramsArray) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | private String argsArrayToString(Object[] paramsArray) { | 
|---|
|  |  |  | String params = ""; | 
|---|
|  |  |  | if (paramsArray != null && paramsArray.length > 0) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | for (Object o : paramsArray) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (StringUtils.isNotNull(o) && !isFilterObject(o)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | try | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (paramsArray != null && paramsArray.length > 0) { | 
|---|
|  |  |  | for (Object o : paramsArray) { | 
|---|
|  |  |  | if (StringUtils.isNotNull(o) && !isFilterObject(o)) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter()); | 
|---|
|  |  |  | params += jsonObj.toString() + " "; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | catch (Exception e) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 忽略敏感属性 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public PropertyPreExcludeFilter excludePropertyPreFilter() | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public PropertyPreExcludeFilter excludePropertyPreFilter() { | 
|---|
|  |  |  | return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 判断是否需要过滤的对象。 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param o 对象信息。 | 
|---|
|  |  |  | * @return 如果是需要过滤的对象,则返回true;否则返回false。 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @SuppressWarnings("rawtypes") | 
|---|
|  |  |  | public boolean isFilterObject(final Object o) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | public boolean isFilterObject(final Object o) { | 
|---|
|  |  |  | Class<?> clazz = o.getClass(); | 
|---|
|  |  |  | if (clazz.isArray()) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | if (clazz.isArray()) { | 
|---|
|  |  |  | return clazz.getComponentType().isAssignableFrom(MultipartFile.class); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else if (Collection.class.isAssignableFrom(clazz)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | } else if (Collection.class.isAssignableFrom(clazz)) { | 
|---|
|  |  |  | Collection collection = (Collection) o; | 
|---|
|  |  |  | for (Object value : collection) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | for (Object value : collection) { | 
|---|
|  |  |  | return value instanceof MultipartFile; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | else if (Map.class.isAssignableFrom(clazz)) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | } else if (Map.class.isAssignableFrom(clazz)) { | 
|---|
|  |  |  | Map map = (Map) o; | 
|---|
|  |  |  | for (Object value : map.entrySet()) | 
|---|
|  |  |  | { | 
|---|
|  |  |  | for (Object value : map.entrySet()) { | 
|---|
|  |  |  | Map.Entry entry = (Map.Entry) value; | 
|---|
|  |  |  | return entry.getValue() instanceof MultipartFile; | 
|---|
|  |  |  | } | 
|---|