IntelligentRecognition/ah-jjsp-service/.svn/pristine/19/197c0422b7bf15c910420b8813c...

412 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.securityControl.common.log.aspect;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.securityControl.common.core.utils.aes.DateTimeHelper;
import com.securityControl.common.log.enums.BusinessType;
import com.securityControl.system.api.domain.SysOperLog;
import com.securityControl.system.api.domain.SysUser;
import com.securityControl.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson2.JSON;
import com.securityControl.common.core.utils.ServletUtils;
import com.securityControl.common.core.utils.StringUtils;
import com.securityControl.common.core.utils.ip.IpUtils;
import com.securityControl.common.log.annotation.Log;
import com.securityControl.common.log.enums.BusinessStatus;
import com.securityControl.common.log.filter.PropertyPreExcludeFilter;
import com.securityControl.common.log.service.AsyncLogService;
import com.securityControl.common.security.utils.SecurityUtils;
/**
* 操作日志记录处理
* ·
*
* @author czc
*/
@Aspect
@Component
@Slf4j
public class LogAspect {
/**
* 排除敏感属性字段
*/
public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
@Autowired
private AsyncLogService asyncLogService;
/**
* 处理完请求后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
//handleLog(joinPoint, controllerLog, null, jsonResult);
}
/**
* 拦截异常操作
*
* @param joinPoint 切点
* @param e 异常
*/
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
handleExceptionLog(joinPoint, controllerLog, e);
}
/**
* 处理异常日志
*
* @param joinPoint
* @param controllerLog
* @param e
*/
protected void handleExceptionLog(final JoinPoint joinPoint, Log controllerLog, final Exception e) {
try {
// *========数据库日志=========*//
SysOperLog operLog = new SysOperLog();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
operLog.setLogType(controllerLog.type());
operLog.setTitle(controllerLog.title());
operLog.setDetail(controllerLog.details());
operLog.setGrade(controllerLog.grade().getInfo());
operLog.setTimes(DateTimeHelper.getNowTime());
operLog.setBusinessType(controllerLog.businessType().ordinal());
// 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
//用户角色及单位
LoginUser loginUser = SecurityUtils.getLoginUser();
if (null != loginUser && null != loginUser.getSysUser()) {
SysUser sysUser = loginUser.getSysUser();
operLog.setRoleName(sysUser.getRoleName());
operLog.setDeptName(sysUser.getOrgName());
operLog.setOperName(sysUser.getUserName());
}
if (e != null) {
operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
operLog.setMethod(className + "." + methodName + "()");
// 设置请求方式
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
//getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 保存数据库
asyncLogService.saveSysLog(operLog);
} catch (Exception exp) {
// 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
}
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param log 日志
* @param operLog 操作日志
*/
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) {
//业务模块
operLog.setTitle(log.title());
operLog.setGrade(log.grade().getInfo());
operLog.setLogType(log.type());
operLog.setSysMenu(log.menu());
operLog.setTimes(DateTimeHelper.getNowTime());
// 设置操作人类别
operLog.setOperatorType(log.operatorType().ordinal());
// 是否需要保存request参数和值
if (log.isSaveRequestData()) {
// 获取参数的信息,传入到数据库中。
setRequestValue(joinPoint, operLog);
}
// 设置action动作
operLog.setBusinessType(log.businessType().ordinal());
BusinessType businessType = log.businessType();
switch (businessType) {
case UPDATE:
if (log.title().equals("日志管理") && log.details().equals("修改日志容量")) {
String url = operLog.getOperUrl();
operLog.setDetail(String.format("日志容量修改为%s", url.substring(url.lastIndexOf("/") + 1)));
} else {
operLog.setDetail(buildDetail(operLog, log));
}
break;
case QUERY:
default:
operLog.setDetail(buildDetail(operLog, log));
break;
}
}
private String buildDetail(SysOperLog operLog, Log log) {
StringBuilder sb = new StringBuilder();
sb.append("用户[");
sb.append(operLog.getOperName());
sb.append("(");
sb.append(operLog.getRoleName());
sb.append(")]");
sb.append("所属单位[");
sb.append(operLog.getDeptName());
sb.append("]");
sb.append("于");
sb.append("[");
sb.append(operLog.getTimes());
sb.append("]");
sb.append("时间在");
sb.append("[");
sb.append(operLog.getOperIp());
sb.append("]");
sb.append("IP上在模块[");
sb.append(operLog.getTitle());
sb.append("]");
sb.append("下执行了[");
sb.append(log.details());
sb.append("]操作");
sb.append("参数为:");
if (null == operLog.getOperParam()) {
sb.append("空,");
} else {
sb.append(operLog.getOperParam());
}
sb.append("操作结果[成功],方法执行时间[&&]ms");
return sb.toString();
}
/**
* 获取请求的参数放到log中
*
* @param operLog 操作日志
*/
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) {
String requestMethod = operLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
}
}
/**
* 参数拼装
*/
private String argsArrayToString(Object[] paramsArray) {
StringBuilder params = new StringBuilder();
if (paramsArray != null && paramsArray.length > 0) {
for (Object o : paramsArray) {
if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
try {
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter());
params.append(jsonObj).append(" ");
} catch (Exception e) {
}
}
}
}
return params.toString().trim();
}
/**
* 忽略敏感属性
*/
public PropertyPreExcludeFilter excludePropertyPreFilter() {
return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES);
}
/**
* 判断是否需要过滤的对象。
*
* @param o 对象信息。
* @return 如果是需要过滤的对象则返回true否则返回false。
*/
@SuppressWarnings("rawtypes")
public boolean isFilterObject(final Object o) {
Class<?> clazz = o.getClass();
if (clazz.isArray()) {
return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
} else if (Collection.class.isAssignableFrom(clazz)) {
Collection collection = (Collection) o;
for (Object value : collection) {
return value instanceof MultipartFile;
}
} else if (Map.class.isAssignableFrom(clazz)) {
Map map = (Map) o;
for (Object value : map.entrySet()) {
Map.Entry entry = (Map.Entry) value;
return entry.getValue() instanceof MultipartFile;
}
}
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
|| o instanceof BindingResult;
}
/**
* 两个..代表所有子目录,最后括号里的两个..代表所有参数
*/
@Pointcut("execution(* com.securityControl.system.controller..*(..)) || execution( * com.sercurityControl..*.controller..*(..))")
public void logPointCut() {
}
/**
* 日志打印
*
* @param joinPoint
* @return Object
* @throws Throwable
*/
@Around("logPointCut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
String name = joinPoint.getSignature().getName();
if (Objects.equals(name,"deviceUpDownToJs")) {
return joinPoint.proceed();
}
long startTime = System.currentTimeMillis();
Object ob = null;
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
assert attributes != null;
if(attributes==null){
return null;
}
HttpServletRequest request = attributes.getRequest();
if(request==null){
return null;
}
String uri = request.getRequestURI();
//控制台打印日志
// printRequestLog(joinPoint, request, uri);
ob = joinPoint.proceed();
long time = System.currentTimeMillis() - startTime;
// log.info("耗时 : {}ms", time);
// *========数据库日志=========*//
SysOperLog sysLog = saveOperLog(joinPoint);
sysLog.setLogTime(time);
if (sysLog.getIsLog()) {
if (StringUtils.isNotEmpty(sysLog.getDetail())) {
sysLog.setDetail(sysLog.getDetail().replaceFirst("&&", String.valueOf(time)));
}
asyncLogService.saveSysLog(sysLog);
}
return ob;
}
/**
* 处理系统日志
*
* @param joinPoint
* @return SysOperLog
*/
private SysOperLog saveOperLog(ProceedingJoinPoint joinPoint) {
SysOperLog operLog = new SysOperLog();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
// 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip);
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
String userId = String.valueOf(SecurityUtils.getUserId());
// log.info("userid:{}", userId);
//用户角色及单位
LoginUser loginUser = SecurityUtils.getLoginUser();
if (null != loginUser && null != loginUser.getSysUser()) {
SysUser sysUser = loginUser.getSysUser();
operLog.setRoleName(sysUser.getRoleName());
operLog.setDeptName(sysUser.getOrgName());
operLog.setOperName(sysUser.getUserName());
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
operLog.setMethod(className + "." + methodName + "()");
// 设置请求方式
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
Method method = getMethod(joinPoint);
Log annotation = method.getAnnotation(Log.class);
operLog.setIsLog(false);
if (null != annotation) {
operLog.setIsLog(true);
getControllerMethodDescription(joinPoint, annotation, operLog);
}
return operLog;
}
/**
* 打印请求日志
*
* @param joinPoint
* @param request
* @param uri
*/
private void printRequestLog(JoinPoint joinPoint, HttpServletRequest request, String uri) {
// log.info("请求地址 : {}", uri);
// 获取请求ContentType
// log.info("请求方式 : {}", request.getMethod());
// 获取真实的ip地址
String ip = StringUtils.getRemoteIp(request);
// log.info("IP : {}", ip);
//String controllerName = joinPoint.getSignature().getDeclaringTypeName();
/// log.info("方法 : {}", joinPoint.getSignature().getName());
Object[] args = joinPoint.getArgs();
// 参数存在且参数不是request且需要记录日志参数
boolean logParamFlag = args != null &&
args.length > 0 &&
!(args[0] instanceof ServletRequest) &&
!(args[0] instanceof MultipartFile) &&
!(args[0] instanceof ServletResponse);
if (logParamFlag) {
String param = JSON.toJSONString(args[0]);
// log.info("参数 : {}", param);
}
String ua = request.getHeader("user-Agent");
// log.info("userAgent{}", ua);
}
/**
* 获取切点的method
*
* @param joinPoint
* @return
*/
private Method getMethod(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
return signature.getMethod();
}
}