100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > SpringBoot + AOP + 自定义注解 + mysql 实现日志管理

SpringBoot + AOP + 自定义注解 + mysql 实现日志管理

时间:2024-07-29 03:50:59

相关推荐

SpringBoot + AOP + 自定义注解 + mysql 实现日志管理

前言

自定义注解相关知识可参考阅读:

/u013045971/article/details/53433874

AOP相关知识可参考阅读:

/qq_36095679/article/details/91979400

1.导入aop依赖

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

2.自定义注解

/*** 自定义操作日志记录注解***/@Target({ ElementType.PARAMETER, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Log{/*** 模块*/public String title() default "";/*** 功能*/public BusinessType businessType() default BusinessType.OTHER;/*** 操作人类别*/public OperatorType operatorType() default OperatorType.MANAGE;/*** 是否保存请求的参数*/public boolean isSaveRequestData() default true;}

操作状态类

public enum BusinessStatus{/*** 成功*/SUCCESS,/*** 失败*/FAIL,}

业务操作类型

public enum BusinessType{/*** 其它*/OTHER,/*** 新增*/INSERT,/*** 修改*/UPDATE,/*** 删除*/DELETE,/*** 授权*/GRANT,/*** 导出*/EXPORT,/*** 导入*/IMPORT,/*** 强退*/FORCE,/*** 生成代码*/GENCODE,/*** 清空数据*/CLEAN,}

日志实体类

/*** 操作日志记录表 oper_log**/@Datapublic class SysOperLog extends BaseEntity{private static final long serialVersionUID = 1L;/** 日志主键 */private Long operId;/** 操作模块 */private String title;/** 业务类型(0其它 1新增 2修改 3删除) */private Integer businessType;/** 业务类型数组 */private Integer[] businessTypes;/** 请求方法 */private String method;/** 请求方式 */private String requestMethod;/** 操作类别(0其它 1后台用户 2手机端用户) */private Integer operatorType;/** 操作人员 */private String operName;/** 操作人员id */private Long userId;/** 部门名称 */private String deptName;/** 请求url */private String operUrl;/** 操作地址 */private String operIp;/** 请求参数 */private String operParam;/** 返回参数 */private String jsonResult;/** 操作状态(0正常 1异常) */private Integer status;/** 错误消息 */private String errorMsg;/** 操作时间 */@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date operTime;

3.切面LogAspect(使用自定义注解动态传参)

/*** 操作日志记录处理**/@Aspect@Componentpublic class LogAspect{private static final Logger log = LoggerFactory.getLogger(LogAspect.class);@Autowiredprivate AsyncLogService asyncLogService;@AutowiredHttpServletRequest request;// 配置织入点@Pointcut("@annotation(mon.log.annotation.Log)")public void logPointCut(){}/*** 处理完请求后执行** @param joinPoint 切点*/@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")public void doAfterReturning(JoinPoint joinPoint, Object jsonResult){handleLog(joinPoint, null, jsonResult);}/*** 拦截异常操作** @param joinPoint 切点* @param e 异常*/@AfterThrowing(value = "logPointCut()", throwing = "e")public void doAfterThrowing(JoinPoint joinPoint, Exception e){handleLog(joinPoint, e, null);}protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult){try{// 获得注解Log controllerLog = getAnnotationLog(joinPoint);if (controllerLog == null){return;}// *========数据库日志=========*//SysOperLog operLog = new SysOperLog();operLog.setStatus(BusinessStatus.SUCCESS.ordinal());// 请求的地址String ip= request.getRemoteAddr();operLog.setOperIp(ip);// 返回参数operLog.setJsonResult(JSON.toJSONString(jsonResult));operLog.setOperUrl(request.getRequestURI());Long userId = SecurityUtils.getUserId();String username = SecurityUtils.getUsername();if (StringUtils.isNotBlank(username)){operLog.setOperName(username);operLog.setUserId(userId);}else{operLog.setOperName("admin");operLog.setUserId(1L);}if (e != null){operLog.setStatus(BusinessStatus.FAIL.ordinal());operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));}// 设置方法名称String className = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();operLog.setMethod(className + "." + methodName + "()");// 设置请求方式operLog.setRequestMethod(ServletUtils.getRequest().getMethod());// 处理设置注解上的参数getControllerMethodDescription(joinPoint, controllerLog, operLog);// 保存数据库asyncLogService.saveSysLog(operLog);}catch (Exception exp){// 记录本地异常日志log.error("==前置通知异常==");log.error("异常信息:{}", exp.getMessage());exp.printStackTrace();}}/*** 获取注解中对方法的描述信息 用于Controller层注解** @param log 日志* @param operLog 操作日志* @throws Exception*/public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception{// 设置action动作operLog.setBusinessType(log.businessType().ordinal());// 设置标题operLog.setTitle(log.title());// 设置操作人类别operLog.setOperatorType(log.operatorType().ordinal());// 是否需要保存request,参数和值if (log.isSaveRequestData()){// 获取参数的信息,传入到数据库中。setRequestValue(joinPoint, operLog);}}/*** 获取请求的参数,放到log中** @param operLog 操作日志* @throws Exception 异常*/private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception{String requestMethod = operLog.getRequestMethod();if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)){String params = argsArrayToString(joinPoint.getArgs());operLog.setOperParam(StringUtils.substring(params, 0, 2000));}}/*** 是否存在注解,如果存在就获取*/private Log getAnnotationLog(JoinPoint joinPoint) throws Exception{Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();if (method != null){return method.getAnnotation(Log.class);}return null;}/*** 参数拼装*/private String argsArrayToString(Object[] paramsArray){String params = "";if (paramsArray != null && paramsArray.length > 0){for (int i = 0; i < paramsArray.length; i++){if (!isFilterObject(paramsArray[i])){try{Object jsonObj = JSON.toJSON(paramsArray[i]);params += jsonObj.toString() + " ";}catch (Exception e){}}}}return params.trim();}/*** 判断是否需要过滤的对象。** @param o 对象信息。* @return 如果是需要过滤的对象,则返回true;否则返回false。*/public boolean isFilterObject(final Object o){return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;}}

日志服务远程接口

/*** 日志服务**/@FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.SYSTEM_SERVICE)public interface RemoteLogService{/*** 保存系统日志** @param sysOperLog 日志实体* @return 结果*/@PostMapping("/operlog")R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog);/*** 保存访问记录** @param username 用户名称* @param status 状态* @param message 消息* @return 结果*/@PostMapping("/logininfor")R<Boolean> saveLogininfor(@RequestParam("username") String username, @RequestParam("status") String status,@RequestParam("message") String message);}

异步调用日志服务

/*** 异步调用日志服务**/@Servicepublic class AsyncLogService{@Autowiredprivate RemoteLogService remoteLogService;/*** 保存系统日志记录*/@Asyncpublic void saveSysLog(SysOperLog sysOperLog){remoteLogService.saveLog(sysOperLog);}}

4.操作日志服务层

/*** 操作日志 服务层**/public interface ISysOperLogService{/*** 新增操作日志* * @param operLog 操作日志对象* @return 结果*/public int insertOperlog(SysOperLog operLog);/*** 查询系统操作日志集合* * @param operLog 操作日志对象* @return 操作日志集合*/public List<SysOperLog> selectOperLogList(SysOperLog operLog);/*** 批量删除系统操作日志* * @param operIds 需要删除的操作日志ID* @return 结果*/public int deleteOperLogByIds(Long[] operIds);/*** 查询操作日志详细* * @param operId 操作ID* @return 操作日志对象*/public SysOperLog selectOperLogById(Long operId);/*** 清空操作日志*/public void cleanOperLog();}

/*** 操作日志 服务层处理**/@Servicepublic class SysOperLogServiceImpl implements ISysOperLogService{@Autowiredprivate SysOperLogMapper operLogMapper;/*** 新增操作日志* * @param operLog 操作日志对象* @return 结果*/@Overridepublic int insertOperlog(SysOperLog operLog){return operLogMapper.insertOperlog(operLog);}/*** 查询系统操作日志集合* * @param operLog 操作日志对象* @return 操作日志集合*/@Overridepublic List<SysOperLog> selectOperLogList(SysOperLog operLog){List<SysOperLog> sysOperLogs = operLogMapper.selectOperLogList(operLog);for (SysOperLog sysOperLog : sysOperLogs) {if(StringUtils.isEmpty(sysOperLog.getOperName())){sysOperLog.setOperName("admin");}}return sysOperLogs;}/*** 批量删除系统操作日志* * @param operIds 需要删除的操作日志ID* @return 结果*/@Overridepublic int deleteOperLogByIds(Long[] operIds){return operLogMapper.deleteOperLogByIds(operIds);}/*** 查询操作日志详细* * @param operId 操作ID* @return 操作日志对象*/@Overridepublic SysOperLog selectOperLogById(Long operId){return operLogMapper.selectOperLogById(operId);}/*** 清空操作日志*/@Overridepublic void cleanOperLog(){operLogMapper.cleanOperLog();}}

5.操作日志数据层

/*** 操作日志 数据层** @author wangyanfei*/public interface SysOperLogMapper{/*** 新增操作日志* * @param operLog 操作日志对象*/public int insertOperlog(SysOperLog operLog);/*** 查询系统操作日志集合* * @param operLog 操作日志对象* @return 操作日志集合*/public List<SysOperLog> selectOperLogList(SysOperLog operLog);/*** 批量删除系统操作日志* * @param operIds 需要删除的操作日志ID* @return 结果*/public int deleteOperLogByIds(Long[] operIds);/*** 查询操作日志详细* * @param operId 操作ID* @return 操作日志对象*/public SysOperLog selectOperLogById(Long operId);/*** 清空操作日志*/public void cleanOperLog();}

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bigunion.system.mapper.SysOperLogMapper"><resultMap type="SysOperLog" id="SysOperLogResult"><idproperty="operId" column="oper_id" /><result property="title"column="title"/><result property="businessType" column="business_type" /><result property="method" column="method" /><result property="requestMethod" column="request_method" /><result property="operatorType" column="operator_type" /><result property="operName" column="oper_name"/><result property="deptName" column="dept_name"/><result property="operUrl" column="oper_url" /><result property="operIp" column="oper_ip" /><result property="operParam"column="oper_param"/><result property="jsonResult"column="json_result" /><result property="status" column="status" /><result property="errorMsg" column="error_msg"/><result property="operTime" column="oper_time"/></resultMap><sql id="selectOperLogVo">select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_param, json_result, status, error_msg, oper_timefrom sys_oper_log</sql><insert id="insertOperlog" parameterType="SysOperLog">insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, user_id,dept_name, oper_url, oper_ip, oper_param, json_result, status, error_msg, oper_time)values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName},#{userId}, #{deptName}, #{operUrl}, #{operIp}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, sysdate())</insert><select id="selectOperLogList" parameterType="SysOperLog" resultMap="SysOperLogResult"><include refid="selectOperLogVo"/><where><if test="title != null and title != ''">AND title like concat('%', #{title}, '%')</if><if test="businessType != null and businessType != ''">AND business_type = #{businessType}</if><if test="businessTypes != null and businessTypes.length > 0">AND business_type in<foreach collection="businessTypes" item="businessType" open="(" separator="," close=")">#{businessType}</foreach></if><if test="status != null">AND status = #{status}</if><if test="operName != null and operName != ''">AND oper_name like concat('%', #{operName}, '%')</if><if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->and date_format(oper_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')</if><if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->and date_format(oper_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')</if></where>order by oper_id desc</select><delete id="deleteOperLogByIds" parameterType="Long">delete from sys_oper_log where oper_id in<foreach collection="array" item="operId" open="(" separator="," close=")">#{operId}</foreach></delete><select id="selectOperLogById" parameterType="Long" resultMap="SysOperLogResult"><include refid="selectOperLogVo"/>where oper_id = #{operId}</select><update id="cleanOperLog">truncate table sys_oper_log</update></mapper>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。