java实现web层的日志切面--java的aop应用

步骤说明:

https://blog.csdn.net/WoddenFish/article/details/82593850  (跟这里写的差不多)
Controller每个方法先加这个自定义注解例如:
@SystemControllerLog(description="新增系统操作日志",moduleName="系统操作日志")

1、引入springboot-aop集成jar
? ? ? ? ? Spring-boot-start-aop

2、application.yml中启用声明
#spring配置
spring:
  #切面启用
  aop:
    proxy-target-class: true
    auto: true

3、自定义一个拦截controller的注解(SystemControllerLog.java)
package com.soc.cloud.config;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * AOP日志记录,注解
 * @author xie
 *
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface  SystemControllerLog {

	/*
	 * 操作说明
	 */
	String description()  default "";

	/*
	 * 模块信息
	 */
	String moduleName() default "";
}

  WebLogAspect.java

package com.soc.cloud.config;

import com.alibaba.fastjson.JSON;
import com.soc.cloud.base.BaseResult;
import com.soc.cloud.base.BaseSocContent;
import com.soc.cloud.data.modal.InterfaceAccessLog;
import com.soc.cloud.data.modal.LogUserMap;
import com.soc.cloud.data.service.DataService;
import com.soc.cloud.util.Validators;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.session.web.http.CookieHttpSessionStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 实现Web层的日志切面
 */
@Aspect
@Component
@Order(-5)
public class WebLogAspect {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	DataService dataService;

	@Autowired
	BaseSocContent baseSocContent;

	/**
	 * 定义一个切入点. 解释下:
	 *
	 * ~ 第一个 * 代表任意修饰符及任意返回值. ~ 第二个 * 任意包名 ~ 第三个 * 代表任意方法. ~ 第四个 * 定义在web包或者子包 ~
	 * 第五个 * 任意方法 ~ .. 匹配任意数量的参数.
	 */
	@Pointcut("execution(public * com.soc.cloud.**.controller..*.*(..))")
	public void webLog() {
	}

	@Pointcut("execution(public * com.soc.cloud.**.service..*.*(..))")
	public void webServiceLog() {
	}

	@Pointcut("execution(public * com.soc.cloud.**.outService..*.*(..))")
	public void outServiceLog() {
	}

	/**
	 * 对外接口调用记录拦截器
	 * @param joinPoint
	 */
	@AfterReturning(returning = "ret", pointcut = "outServiceLog()")
	public void doOutAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {

		InterfaceAccessLog interfaceAccessLog = new InterfaceAccessLog();

		//调用方
		String callerName = this.getMethodDescription(joinPoint,false);
		//调用接口功能说明
		String moduleName = this.getMethodModuleName(joinPoint,false);
		//传入内容
		Object[] paramsArray = joinPoint.getArgs();
		String params = subMaxString(argsArrayToString(paramsArray));

		try {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			if (attributes == null)
				return;
			HttpServletRequest request = attributes.getRequest();
			if("".equals(callerName)){
				//todo 如果调用方为传送过来的变量,则需要重新写获取参数内容
			}
			//记录调用url
			String uri = request.getRequestURI();
			//记录调用IP
			String Ip = getIpAddrNew(request);
			//返回结果内容
			String result = subMaxString(JSON.toJSONString(ret)).replace("\\","");
			//返回结果
			String resultCode = "1";
			if (ret instanceof BaseResult) {
				JSONObject object = JSONObject.fromObject(ret);
				if (!("0").equals(object.get("returnCode").toString())) {
					resultCode = "0";
				}
			}else{
				resultCode = "0";
			}
			interfaceAccessLog.setUrl(uri);
			interfaceAccessLog.setIp(Ip);
			interfaceAccessLog.setReturnInfo(result);
			interfaceAccessLog.setSuccessTag(resultCode);
		}catch (Exception e){
			interfaceAccessLog.setRemark(subMaxString(e.getMessage()));
		}
		interfaceAccessLog.setCallerName(callerName);
		interfaceAccessLog.setFunctionName(moduleName);
		interfaceAccessLog.setRequestInfo(params);

		dataService.insertInterfaceLog(interfaceAccessLog);
	}

	@AfterThrowing(pointcut = "outServiceLog()", throwing = "e")
	public void doOutAfterThrowing(JoinPoint joinPoint, Throwable e)  throws Throwable {
		this.insertLog(joinPoint, "0", true);
		InterfaceAccessLog interfaceAccessLog = new InterfaceAccessLog();
		//调用方
		String callerName = this.getMethodDescription(joinPoint, false);
		//调用接口功能说明
		String moduleName = this.getMethodModuleName(joinPoint, false);
		//传入内容
		Object[] paramsArray = joinPoint.getArgs();
		String params = subMaxString(argsArrayToString(paramsArray));
		interfaceAccessLog.setCallerName(callerName);
		interfaceAccessLog.setFunctionName(moduleName);
		interfaceAccessLog.setRequestInfo(params);
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		try {
			e.printStackTrace(pw);
		} finally {
			pw.close();
		}
		interfaceAccessLog.setRemark(subMaxString(sw.toString()));
		dataService.insertInterfaceLog(interfaceAccessLog);
	}

	/**
	 * controcller层拦截器
	 * @param joinPoint
	 */
	@Before("webLog()")
	public void doBefore(JoinPoint joinPoint) {
		try {
			long beginTime = System.currentTimeMillis();
			// 接收到请求,记录请求内容
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			if (attributes == null)
				return;
			HttpServletRequest request = attributes.getRequest();
			String beanName = joinPoint.getSignature().getDeclaringTypeName();
			String methodName = joinPoint.getSignature().getName();
			String uri = request.getRequestURI();
			String remoteAddr = getIpAddr(request);
			String sessionId = request.getSession().getId();
			// String user = (String) request.getSession().getAttribute("user");
			String method = request.getMethod();
			String contentType = request.getContentType();
			String params = "";
			if (contentType == null) {
				contentType = "";
			}
			if ("POST".equals(method) && contentType.contains("json")) {
				Object[] paramsArray = joinPoint.getArgs();
				params = argsArrayToString(paramsArray);
			} else {
				Map<?, ?> paramsMap = (Map<?, ?>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
				params = paramsMap.toString();
			}
			logger.info("请求路径=" + uri + "; beanName=" + beanName + "; IP地址=" + remoteAddr + "; 方法名=" + methodName
					+ "; 参数=" + params);

		} catch (Exception e) {
			logger.error("***操作请求日志记录失败doBefore()***", e);
		}
	}

	@AfterReturning(returning = "ret", pointcut = "webLog()")
	public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {

		// 处理完请求,返回内容
		if (ret instanceof BaseResult) {
			JSONObject object = JSONObject.fromObject(ret);
			if (("0").equals(object.get("returnCode").toString())) {
				this.insertLog(joinPoint, "1",true);
			} else {
				this.insertLog(joinPoint, "0",true);
			}
		}
		logger.info("RESPONSE : " + JSON.toJSONString(ret));
	}

	@AfterThrowing(pointcut = "webLog()", throwing = "e")
	public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
		this.insertLog(joinPoint, "0",true);
		e.printStackTrace();
	}

	/**
	 * service层拦截器
	 */
	@AfterReturning(returning = "ret", pointcut = "webServiceLog()")
	public void doAfterReturningService(JoinPoint joinPoint, Object ret) throws Throwable {

		// 处理完请求,返回内容
		if (ret instanceof BaseResult) {
			JSONObject object = JSONObject.fromObject(ret);
			if (("0").equals(object.get("returnCode").toString())) {
				this.insertLog(joinPoint, "1",false);
			} else {
				this.insertLog(joinPoint, "0",false);
			}
			try {
				logger.info("RESPONSE : " + JSON.toJSONString(ret));
			} catch (Exception e) {
				logger.info("RESPONSE : " + null);
			}
		}else if(ret instanceof String && ((String) ret).contains("returnCode")){
			JSONObject object = JSONObject.fromObject(ret);
			if (("0").equals(object.get("returnCode").toString())) {
				this.insertLog(joinPoint, "1",false);
			} else {
				this.insertLog(joinPoint, "0",false);
			}
			try {
				logger.info("RESPONSE : " + JSON.toJSONString(ret));
			} catch (Exception e) {
				logger.info("RESPONSE : " + null);
			}
		}
	}

	@AfterThrowing(pointcut = "webServiceLog()", throwing = "e")
	public void doAfterThrowingService(JoinPoint joinPoint, Throwable e) {
		boolean flag = false;
		try {

			if(Validators.isNotnull(this.getMethodModuleName(joinPoint,false))){
				flag = true;
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		if(flag){
			this.insertLog(joinPoint, "0",false);
		}
		e.printStackTrace();
	}

	/**
	 * 请求参数拼装
	 *
	 * @param paramsArray
	 * @return
	 */
	private String argsArrayToString(Object[] paramsArray) {
		String params = "";
		if (paramsArray != null && paramsArray.length > 0) {
			for (int i = 0; i < paramsArray.length; i++) {
				if(paramsArray[i] instanceof  Map){
					Object jsonObj = JSON.toJSON(paramsArray[i]);
					params += jsonObj.toString() + " ";
				}
			}
		}
		return params.trim();
	}

	/**
	 * 截取最长2000个字符串
	 * @param str
	 * @return
	 */
	private String subMaxString(String str){
		String print = null;
		if(str.length()>2000){
			print = str.substring(0,1999);
		}else{
			print = str;
		}
		return print;
	}

	public  String getIpAddrNew(HttpServletRequest request)
	{
		String ip = request.getHeader("X-Real-IP");
		if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip))
		{
			return ip;
		}
		ip = request.getHeader("X-Forwarded-For");
		if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip))
		{
			// 多次反向代理后会有多个IP值,第一个为真实IP。
			int index = ip.indexOf(',');
			if (index != -1)
			{
				return ip.substring(0, index);
			}
			else
			{
				return ip;
			}
		}
		else
		{
			return request.getRemoteAddr();
		}
	}

	// 获取客户端IP
	private String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 获取方法的操作描述
	 * 
	 * @param joinPoint
	 * @return
	 * @throws Exception
	 */
	private String getMethodDescription(JoinPoint joinPoint,boolean isControll) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		String description = "";
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					if(isControll){
						if (Validators.isNotnull(method.getAnnotation(SystemControllerLog.class))) {
							description = method.getAnnotation(SystemControllerLog.class).description();
							break;
						}
					}else{
						if (Validators.isNotnull(method.getAnnotation(SystemServiceLog.class))) {
							description = method.getAnnotation(SystemServiceLog.class).description();
							break;
						}
					}

				}
			}
		}
		return description;
	}

	/**
	 * 获取方法的模块
	 * 
	 * @param joinPoint
	 * @return
	 * @throws Exception
	 */
	private String getMethodModuleName(JoinPoint joinPoint,boolean isControll) throws Exception {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class targetClass = Class.forName(targetName);
		Method[] methods = targetClass.getMethods();
		String moduleName = "";
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				Class[] clazzs = method.getParameterTypes();
				if (clazzs.length == arguments.length) {
					if (isControll) {
						if (Validators.isNotnull(method.getAnnotation(SystemControllerLog.class))) {
                            moduleName = method.getAnnotation(SystemControllerLog.class).moduleName();
                            break;
                        }
					} else {
						if (Validators.isNotnull(method.getAnnotation(SystemServiceLog.class))) {
							moduleName = method.getAnnotation(SystemServiceLog.class).moduleName();
							break;
						}
					}
				}
			}
		}
		return moduleName;
	}

	/**
	 * 入库
	 * @param joinPoint
	 * @param flag
	 */
	public void insertLog(JoinPoint joinPoint,String flag,boolean isControll){
		try {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
			String remoteAddr = "";
			String url = "";
			if(attributes!=null){
				HttpServletRequest request = attributes.getRequest();
				url = request.getRequestURI();
				remoteAddr = getIpAddr(request);
			}else{
				remoteAddr = "127.0.0.1";
			}

			//String user = (String) request.getSession().getAttribute("user");
			Integer userId = null;
			try {
				userId = baseSocContent.getUserId();
			} catch (Exception e) {
				logger.info("未找到相关用户");
				userId = 1;
			}
			String description = this.getMethodDescription(joinPoint,isControll);
			String moduleName = this.getMethodModuleName(joinPoint,isControll);
			
			
			// 操作日志过滤
			if(Validators.isNotnull(url)){
				if(url.contains("/baselineCtccTask/add")
						||url.contains("/agentInfo/agentClient")
						||url.contains("/socketClient/forward")
						
						){
					return;
				}
			}
			
			if(Validators.isNotnull(moduleName)){
				/*
				 * 日志信息入库
				 */
				LogUserMap logUser = new LogUserMap();
				logUser.setIpAddress(remoteAddr);
				logUser.setOperationType("sys");
				logUser.setModuleName(moduleName);
				logUser.setSuccessTag(flag);
				logUser.setOperationContent(description);
				if (Validators.isNotnull(userId+"")) {
					logUser.setUserId(userId+"");
				} else {
					logUser.setUserId("-1");
				}
				
				Object[] args = joinPoint.getArgs();
				if (args != null && args.length > 0) {
					Object obj = args[0];
					if (obj instanceof Map) {
						Map<String, Object> map = (Map<String, Object>) obj;
						Object userIdStr = map.get("userId");
						Object userPassword = map.get("userPassword");
						if (Validators.isNotnull(userIdStr) && Validators.isNotnull(userPassword)) {
							logUser.setUserId(userIdStr+"");
						}
					}
				}
				
				dataService.insertLog(logUser);
			}
		} catch (Exception e2) {
			String err = e2.getMessage();
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			if (attributes != null) {
				HttpServletRequest request = attributes.getRequest();
				String uri = request.getRequestURI();
				err = "uri:" + uri + " " + err;
			}
			logger.error("***操作请求日志记录失败*** " + err);
		}
	}

}

  LogUserMap.java  -- 日志信息入库 表

package com.soc.cloud.data.modal;

import java.io.Serializable;
import java.util.Date;

public class LogUserMap implements Serializable {

	/**
	 *
	 */
	private static final long serialVersionUID = 4174117259191059321L;

	private Integer logId;

	private String ipAddress;

	private String userId;

	private String moduleName;

	private String operationType;

	private String operationContent;

	private Date createTime;

	private String successTag;


	public LogUserMap() {
		super();
		// TODO Auto-generated constructor stub
	}



	public LogUserMap(Integer logId, String ipAddress, String userId,
			String moduleName, String operationType, String operationContent,
			Date createTime, String successTag) {
		super();
		this.logId = logId;
		this.ipAddress = ipAddress;
		this.userId = userId;
		this.moduleName = moduleName;
		this.operationType = operationType;
		this.operationContent = operationContent;
		this.createTime = createTime;
		this.successTag = successTag;
	}



	public Integer getLogId() {
		return logId;
	}

	public void setLogId(Integer logId) {
		this.logId = logId;
	}


	public String getModuleName() {
		return moduleName;
	}

	public void setModuleName(String moduleName) {
		this.moduleName = moduleName;
	}

	public String getOperationType() {
		return operationType;
	}

	public void setOperationType(String operationType) {
		this.operationType = operationType;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getSuccessTag() {
		return successTag;
	}

	public void setSuccessTag(String successTag) {
		this.successTag = successTag;
	}

	public String getOperationContent() {
		return operationContent;
	}

	public void setOperationContent(String operationContent) {
		this.operationContent = operationContent;
	}



	public String getIpAddress() {
		return ipAddress;
	}



	public void setIpAddress(String ipAddress) {
		this.ipAddress = ipAddress;
	}



	public String getUserId() {
		return userId;
	}



	public void setUserId(String userId) {
		this.userId = userId;
	}

}

  

posted @ 2022-02-15 16:52  梦幻&浮云%  阅读(487)  评论(0)    收藏  举报