一、关于AOP
无侵入的方式作用于方法当中,在controller层拦截并打印请求报文和响应报文
二、annotation类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @class ApiLog
* @classdesc 用于打印请求和响应日志的注解
* @author chh
* @date 2020/8/26 14:43
* @version 1.0.0
* @see
* @since
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiLog {
}
三、切面实现类
package com.boss.xtrain.log.api.aop;
import com.boss.xtrain.core.context.BaseContextHolder;
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.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* @class MyApiLogAspect
* @classdesc 实现ApiLog的功能,即打印请求日志和响应日志
* @author chh
* @date 2020/8/26 15:07
* @version 1.0.0
* @see
* @since
*/
@Aspect
@Component
@Slf4j
public class MyApiLogAspect {
/**
* 记录业务请求的时间
*/
private long req;
private String reqTime;
/**
* @param: void
* @return: void
* @desc: 定义空方法用于切点表达式
* @see
* @since
*/
@Pointcut("@annotation(com.boss.xtrain.log.api.annotation.ApiLog)")
public void pointcut(){
//do nothing just for filtering
}
/**
* @param: [joinPoint]
* @return: void
* @desc: 在进入controller之前拦截并打印请求报文日志
* @see
* @since
*/
@Before("pointcut()")
public void printRequestDatagram(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = getIpAddress(request);
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
SimpleDateFormat dateFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
req = System.currentTimeMillis();
reqTime = dateFormat.format (new Date(req));
Object[] args = joinPoint.getArgs ();
log.info ("==> 拦截到请求
"
+ "==> 请求者工号:" + BaseContextHolder.getUserCode() + "
"
+ "==> 请求者IP:" + ip + "
"
+ "==> 请求时间:" + reqTime + "
"
+ "==> 请求接口:" + request.getMethod() + " " + request.getRequestURL() + "
"
+ "==> 请求方法:" + method.getName() + "
"
+ "==> 参数内容:"+ Arrays.toString(args));
}
/**
* @param: [joinPoint]
* @return: java.lang.Object
* @desc: 返回信息后,打印应答报文的日志
* @see
* @since
*/
@Around("pointcut()")
public Object printResponseDatagram(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
result = joinPoint.proceed ();
long respTime = System.currentTimeMillis() - req;
String d = String.valueOf(respTime);
log.info ( "<== 响应请求
"
+ "<== 请求时间:" + reqTime + "
"
+ "<== 请求耗时:" + Double.parseDouble(d)/1000 + "s
"
+ "<== 应答内容:" + result );
return result;
}
/**
* @param: [request]
* @return: java.lang.String
* @desc: 获取IP地址
* @see
* @since
*/
private String getIpAddress(HttpServletRequest request){
final String UNKNOWN = "unknown";
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.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}