引言
在实际项目中,通常需要将请求controller的参数进行打印,便于查找bug,快速定位问题。如果每个controller中的请求都写上日志,会让代码很凌乱,这里我们就使用spring aop概念,将请求入参统一打印
代码如下
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Aspect //切面类
@Component //Spring容器管理
public class LogAspect {
@Pointcut("execution(public * com.xxx.service.controller.*.*(..))")
public void LogAspect(){}
@Around("LogAspect()")
public Object deAround(ProceedingJoinPoint pjp) throws Throwable{
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
HttpServletRequest request = sra.getRequest();
//ip地址
String ipaddress;
if (request.getHeader("x-forwarded-for") == null) {
ipaddress = request.getRemoteAddr();
} else {
ipaddress = request.getHeader("x-forwarded-for");
}
String url = request.getRequestURL().toString();
String method = request.getMethod();
String queryString = request.getQueryString();
Object[] args = pjp.getArgs();
String params = "";
//获取请求参数集合并进行遍历拼接
if(args.length>0){
if("POST".equals(method)){
Object object = args[0];
Map map = getKeyAndValue(object);
params = JSON.toJSONString(map);
}else if("GET".equals(method)){
params = queryString;
}
}
//请求信息打印
log.info("请求地址:{},请求ip:{},请求类型:{},请求参数:{}",url,ipaddress,method,params);
//返回信息打印
Object result = pjp.proceed();
Gson gson = new Gson();
log.info("请求结束===返回值:" + gson.toJson(result));
return pjp.proceed();
}
public static Map<String, Object> getKeyAndValue(Object obj) {
Map<String, Object> map = new HashMap<String, Object>();
// 得到类对象
Class userCla = (Class) obj.getClass();
/* 得到类中的所有属性集合 */
Field[] fs = userCla.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
Field f = fs[i];
f.setAccessible(true); // 设置些属性是可以访问的
Object val;
try {
val = f.get(obj);
// 得到此属性的值
map.put(f.getName(), val);// 设置键值
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return map;
}
}