使用的是AOP的环绕通知注解@Around实现
1、首先建好表和实体(此处只展示实体类):
/** * <p> * 请求日志记录 * </p> */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class RequestLog implements Serializable { private static final long serialVersionUID = 1L; /** * bo */ @TableId(value = "BO", type = IdType.AUTO) private Integer bo; /** * 请求url */ @TableField("URL") private String url; /** * ip */ @TableField("IP") private String ip; /** * 请求方式 */ @TableField("REQUEST_TYPE") private String requestType; /** * 请求类方法 */ @TableField("METHOD_NAME") private String methodName; /** * 请求参数 */ @TableField("REQUEST_PARAM") private String requestParam; /** * 响应参数 */ @TableField("RESPONSE_PARAM") private String responseParam; /** * 耗时(毫秒) */ @TableField("ELAPSED_TIME") private Long elapsedTime; /** * 模块名 */ @TableField("MODULE_NAME") private String moduleName; /** * 创建人 */ @TableField("CREATE_USER") private String createUser; /** * 创建时间 */ @TableField("CREATE_DATE") private Date createDate; }
2、使用环绕通知和request 获取相关信息存储(其中添加了配置文件内的参数控制日志记录是否打开)
/** * @description: 使用AOP保存所有请求信息 * @author: yuanguonan * @date: 2021/8/17 10:02 */ @Aspect @Component public class RequestAopLogConfig { @Value("${request.log.isOpen}") private boolean isOpen; @Value("${request.log.moduleName}") private String moduleName; @Autowired private RequestLogService requestLogService; //切点(所有请求) @Pointcut("execution(public * com.itl.mes.*.provider.controller..*.*(..))") private void controllerAspect() { } @Around("controllerAspect()") public Object process(ProceedingJoinPoint joinPoint) throws Throwable { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); //开始时间 long startTime = new Date().getTime(); //响应结果 Object result = joinPoint.proceed(); //结束时间 long endTime = new Date().getTime(); //是否开启日志记录 if (isOpen) { RequestLog requestLog = new RequestLog(); //模块名称 requestLog.setModuleName(moduleName); //IP requestLog.setIp(getRemoteHost(request)); //全路径 requestLog.setUrl(request.getRequestURL().toString()); //请求参数 requestLog.setRequestParam(postHandle(filterParamList(joinPoint))); //响应参数 requestLog.setResponseParam(postHandle(result)); //请求类型 requestLog.setRequestType(request.getMethod()); //类和方法名称 requestLog.setMethodName(joinPoint.getTarget().getClass().getSimpleName() + "." + joinPoint.getSignature().getName()); //耗时 requestLog.setElapsedTime(endTime - startTime); //创建人 requestLog.setCreateUser(UserUtils.getCurrentUser() != null ? UserUtils.getCurrentUser().getUserName() : "testAdmin"); requestLogService.save(requestLog); } return result; } /** * 获取目标主机的ip * * @param request * @return */ private String getRemoteHost(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 "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; } /** * 返回数据 * * @param retVal * @return */ private String postHandle(Object retVal) { if (null == retVal) { return ""; } return JSON.toJSONString(retVal); } /** * 过滤参数列表 * * @param joinPoint * @return */ private List<Object> filterParamList(ProceedingJoinPoint joinPoint) { List<Object> paramsList = new ArrayList<>(); Object[] arrays = joinPoint.getArgs(); for (int i = 0; i < arrays.length; i++) { if (!(arrays[i] instanceof HttpServletRequest)) { paramsList.add(arrays[i]); } } return paramsList; } }
3、测试后基本满足需求: