@Aop 记录请求日志案例
Posted 健身小白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@Aop 记录请求日志案例相关的知识,希望对你有一定的参考价值。
mport lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
/**
* 系统日志:切面处理类
*/
@Aspect
@Component
@Order()
@Slf4j
public class SysLogAspect {
@Autowired
private SysLogService sysLogService;
//定义切点 @Pointcut
//在注解的位置切入代码
@Pointcut("@annotation( com.xcx.vcxcx.common.logConfig.MyLog)")
public void logPoinCut() {
}
@AfterReturning(value = "logPoinCut()", returning = "result")
public void saveSysLog(JoinPoint joinPoint,Object result) {
//保存日志
SysLog sysLog = new SysLog();
//从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入点所在的方法
Method method = signature.getMethod();
//获取操作
MyLog myLog = method.getAnnotation(MyLog.class);
if (myLog != null) {
String value = myLog.value();
sysLog.setOperation(value);//保存获取的操作
}
//获取请求的类名(暂时不需要)
String className = joinPoint.getTarget().getClass().getName();
//获取请求的方法名
String methodName = method.getName();
sysLog.setMethod(className+"."+methodName);
//请求的参数
Object[] args = joinPoint.getArgs();
HashMap<String,Object> map = new HashMap<>();
Signature signatures = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signatures;
String[] parameterNames = methodSignature.getParameterNames();
int index = 0;
for(String str : parameterNames) {
map.put(str,args[index++]);
}
sysLog.setParams(map.toString());
sysLog.setCreateDate(new Date());
//获取用户ip地址
HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
sysLog.setIp(IPUtils.getIpAddr(request));
//获取openId
sysLog.setOpenId(request.getServletContext().getAttribute("openid").toString());
//获取返回值
sysLog.setResult(result.toString());
//输出打印
log.info("save op log with sysLog {}",sysLog.toString());
//调用service保存SysLog实体类到数据库
sysLogService.save(sysLog);
}
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class SysLog implements Serializable {
private String openId; //用户id
private String operation; //操作
private String method; //方法名
private String params; //参数
private String ip; //ip地址
private String result;//返回值
private Date createDate; //操作时间
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SysLogService {
@Autowired
private SaveMapper saveMapper;
public Integer save(SysLog sysLog) {
int flag = saveMapper.save(sysLog);
return flag;
}
}
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.ResultType;
@Mapper
public interface SaveMapper {
@Insert("INSERT into vx_self_log (openId,operation,method,params,result,ip,createDate)VALUES(#{sysLog.openId},#{sysLog.operation},#{sysLog.method},#{sysLog.params},#{sysLog.result},#{sysLog.ip},now());")
@ResultType(Integer.class)
Integer save(@Param("sysLog")SysLog sysLog) ;
}
import java.lang.annotation.*;
/**
* 自定义注解类
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyLog {
String value() default "";
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
public class IPUtils {
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 获取IP地址
* 使用nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = null;
try {
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
logger.error("IPUtils ERROR ", e);
}
// 使用代理,则获取第一个IP地址
if (StringUtils.isEmpty(ip) && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
}
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
public class HttpContextUtil {
private HttpContextUtil(){}
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
}
}
使用注解 @MyLog(value = “方法描述”)就实现了记录某个接口的请求参数
以上是关于@Aop 记录请求日志案例的主要内容,如果未能解决你的问题,请参考以下文章