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;
}
}

浙公网安备 33010602011771号