乐趣区

关于java:spring-boot-通过aop-记录操作日志-操作数据内容-解决requestbody无法获取数据

上码

1. 引入 aop 依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 注解类

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;
/**
 * 操作日志注解
 */
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented
public @interface OperLog {String operModul() default "";// 操作模块名称
    String operType() default "";// 操作类型
    String operDesc() default "";// 性能形容}

3 切面办法

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
 * 切面解决类,操作日志解决
 */
@Aspect
@Component
public class OperLogAspect {
    @Autowired
 private TSysLogService logService;
    private Logger logger = LoggerFactory.getLogger(getClass());
    private String params ="";
    @Pointcut("@annotation(org.student.aspect.OperLog)")
    public void operLogPoinCut() {}
    @Before("@annotation(org.student.aspect.OperLog)")
    public void beforeController(JoinPoint joinPoint){Object[] o = joinPoint.getArgs();
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        Map<String, String> rtnMap = converMap(request.getParameterMap());
        // 通过判断 contenttype 辨别数据类型
        if(request.getContentType().equals("application/json")){params = JSONObject.toJSONString(o[0]);
        }else {params = JSON.toJSONString(rtnMap);
        }
        request.setAttribute("body",o[0]);
    }
    @AfterReturning(value = "operLogPoinCut()", returning = "keys")
    public void saveOperLog(JoinPoint joinPoint, Object keys) {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes
            .resolveReference(RequestAttributes.REFERENCE_REQUEST);
            
        //TUser loginUser = userService.getLoginUser(request); // 获取用户信息
        TSysLog operlog = new TSysLog();
        try {MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            OperLog opLog = method.getAnnotation(OperLog.class);
            if (opLog != null) {String operModul = opLog.operModul();
                String operType = opLog.operType();
                String operDesc = opLog.operDesc();
                operlog.setOperMod(operModul); // 模块
                operlog.setOperType(operType); // 类型
                operlog.setOperDesc(operDesc); // 形容
            }
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = method.getName();
            methodName = className + "." + methodName;
            operlog.setOperMethod(methodName);// 申请办法名
            operlog.setOperRequParam(params);// 申请数据
            operlog.setOperRespParam(JSON.toJSONString(keys));// 响应数据
            //operlog.setUserId(loginUser.getId());
            //operlog.setAccount(loginUser.getAccount());
            //operlog.setDepartId(loginUser.getDepartId());
            operlog.setOperIp(getRemoteAddr(request));// 申请 ip
            operlog.setOperUri(request.getRequestURI());
            logService.insertLog(operlog);
        } catch (Exception e) {e.printStackTrace();
        }
    }
    /**
 * 转换 request 申请参数
 *
 */ public Map<String, String> converMap(Map<String, String[]> paramMap) {Map<String, String> rtnMap = new HashMap<String, String>();
        for (String key : paramMap.keySet()) {rtnMap.put(key, paramMap.get(key)[0]);
        }
        return rtnMap;
    }
    public static String getRemoteAddr(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.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;
    }
}

4. 应用案例

@RequestMapping(value = "/saveInfo", method = RequestMethod.POST)
@OperLog(operDesc = "性能形容", operType ="操作类型", operModul = "操作模块名称")
public ResponseResult saveInfo(@RequestBody TStudent student) {ResponseResult<Integer> result = studentService.saveInfo(student);
    return result;
}

5. 表构造及类

import lombok.Data;
import java.util.Date;
@Data
public class TSysLog {
    private Long id;
    private String operMod;
    private String operType;
    private String operDesc;
    private String operRequParam;
    private String operRespParam;
    private String account;
    private Long userId;
    private Long departId;
    private String operUri;
    private String operIp;
    private Date createTime;
    private String operVar;
    private String operExtra;
    private String operMethod;
}

退出移动版