利用aop来实现web项目请求中的参数,从而实现日志的记录,是很常用的功能。自己从网上找到了一些例子和自己的总结。
1.声明自定义注解
@Target(ElementType.METHOD) // 方法注解
@Retention(RetentionPolicy.RUNTIME) // 运行时可见
public @interface WebLog {
String operateType();// 记录日志的操作类型
}
2.实现aop接口
@Aspect
@Component
public class WebLogAspect {
private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
@Resource
private LogMapper logMapper;
@Around("@annotation(com.company.project.annotation.WebLog)")
public Object logAfterController(ProceedingJoinPoint pjp) {
//获取当前请求对象
//这个RequestContextHolder是Springmvc提供来获得请求的东西
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
// 获取方法签名
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
// 请求的方法
String methodname = methodSignature.getMethod().getName();
//请求的类名
String ClassName=pjp.getSignature().getDeclaringTypeName();
//请求的参数
String ArgsName=Arrays.toString(pjp.getArgs());
//IP地址
String ipdress=request.getRemoteAddr();
//请求URL
String URL=request.getRequestURL().toString();
//请求方式
String WebMethod=request.getMethod();
// 创建一个日志对象(准备记录日志)
Log logSys = new Log();
//编号
logSys.setLognum(UUID.randomUUID().toString());
// 获取指定方法上面的注解
WebLog logAnno = methodSignature.getMethod().getAnnotation(WebLog.class);
// 获取操作描述的属性值
String operateType = logAnno.operateType();
logSys.setContent(operateType);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
Date d= new Date();
String opertime = sdf.format(d);
logSys.setCtime(new Date());
//获取用户名 这里是使用了springSecurity 获取用户名 如果没有使用 可以删除
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
//设置操作人id
logSys.setPmid(Integer.valueOf(authentication.getName()));
}
else {
logSys.setPmid(-1);
}
// 记录下请求内容
logger.info("################请求地址为URL : " + URL);
logger.info("################请求方式为 : " + WebMethod);
logger.info("################IP地址为 : " + ipdress);
logger.info("################传递的参数为 : " + ArgsName);
logger.info("################调用的方法名 : " +methodname);
logger.info("################完整类名为 : " + ClassName + "." + methodname);
logger.info("################操作时间 : "+opertime );
logger.info("################操作类型 : "+operateType);
Object result =null;
try {
//代理方法执行
result= pjp.proceed();
logSys.setResult("操作成功");
logMapper.insert(logSys);
logger.info("################备注 : "+"操作成功");
} catch (Throwable throwable) {
logSys.setResult("操作失败:"+throwable.getMessage());
logMapper.insert(logSys);
logger.info("################备注 : "+"操作失败:"+throwable.getMessage());
throw throwable;
}
return result;
}
}
3.使用方法
在需要记录日志的方法中,使用该注解,如:登录成功,修改,删除等等。一般用在controller和service中
/**
* 添加广告
* @param
* @return
*/
@PostMapping("/api/v1/notice/ad")
@WebLog(operateType = "添加广告")
public Result add(@RequestParam(value = "adName",required = true)String adNam,
@RequestParam(value = "adFile",required = false) MultipartFile adFile,
@RequestParam(value = "des",required = true)String des){
}
4.在使用了该注解的地方,可以手动抛出一些异常 , aop也能捕获到 如下
throw new ServiceException("广告增加失败");
5. 这样就会生成一个日志记录。使用aop实现