该功能写在子模块Common中,其它模块引用该模块后在某些方法上实现对应的注解即可实现用户操作日志的记录
1.创建自定义注解类OperationAnnotation
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Holley * @description 操作日志 * @create 2020-08-24 10:37 **/ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface OperationAnnotation { /** * 操作内容 * @return */ String content(); }
2.实现切面通知类OperationAspect
package com.sgeye.cloud.aop; import com.sgeye.cloud.annotation.OperationAnnotation; import com.sgeye.cloud.constant.UserConstant; import com.sgeye.cloud.mapper.OperationMapper; import com.sgeye.cloud.model.JWToken; import com.sgeye.cloud.model.Operation; import com.sgeye.cloud.util.IpUtil; import com.sgeye.cloud.util.RedisUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; 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.util.Arrays; import java.util.HashMap; /** * @author Holley * @description 请输入一句话进行描述 * @create 2020-08-24 10:58 **/ @Slf4j @Order @Aspect @Component public class OperationAspect { @Autowired private RedisUtils redisUtils; @Autowired private OperationMapper operationMapper; @After("@annotation(com.sgeye.cloud.annotation.OperationAnnotation)") public void OperationHandler(JoinPoint joinPoint){ log.info("开始记录操作日志》》》》》》》》》》》》》"); ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); Operation operation = new Operation(); operation.setIp(IpUtil.getIp(request)); // 获取注解 MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); Method method = methodSignature.getMethod(); operation.setMethodName(method.getName()); operation.setClassName(method.getDeclaringClass().getName()); operation.setParams(Arrays.toString(joinPoint.getArgs())); OperationAnnotation operationAnnotation = method.getAnnotation(OperationAnnotation.class); operation.setContent(operationAnnotation.content()); String token = request.getHeader("token"); if (StringUtils.isNotEmpty(token)) { JWToken jwToken = new JWToken(); //获取解析token中的值 HashMap<String, Object> map = jwToken.parseJWT(token); Long uid = null; String account = null; Long hid = null; if (map != null) { if (map.get("uid") != null && map.get("uid").toString() != "") { uid = Long.valueOf(map.get("uid").toString()); if(redisUtils.get(UserConstant.HOSPITAL + uid) != null){ hid = Long.valueOf((Integer)redisUtils.get(UserConstant.HOSPITAL + uid)); } } if (map.get("account") != null) { account = (String) map.get("account"); } operation.setAccount(account); operation.setHid(hid); operation.setUid(uid); } }
// 插入数据库 operationMapper.insertOperation(operation); log.info("结束记录操作日志》》》》》》》》》》》》》"); } }
3.在接口上添加注解OperationAnnotation
@GetMapping("/{hid}") @OperationAnnotation(content = "根据医院hid查询医院详细信息") public Object getHospitalInfo(@PathVariable("hid") Long hid, @RequestParam(name = "request_from",required = false)String requestFrom){ HospitalDto hospitalDto = hospitalService.getHospitalInfoByHid(hid); if (CommonConstant.RESQUEST_FROM_APPLET.equals(requestFrom)) { HospitalVo hospitalVo = DozerUtil.map(hospitalDto,HospitalVo.class); return hospitalVo; } HospitalOfEfileVo hospitalOfEfileVo = DozerUtil.map(hospitalDto,HospitalOfEfileVo.class); return new Response(hospitalOfEfileVo,"查询成功"); }
参考文档:
1.如何获取到请求来源的真实IP:https://www.cnblogs.com/chinaifae/p/10189012.html
2.切面编程内容详解:https://www.cnblogs.com/wangshen31/p/9379197.html