通常情况下我们可以用拦截器拦截相应的方法然后生成日志文件记录到数据库中,但此时记录的日志我们只能看到调用了哪些类 类有哪些参数,请求参数有哪些等等..有没有一目了然的方法直接展现系统的日志的?比如说每一条日志都有相应的描述什么的~~?
采用注解的方式来拦截系统日志
- 添加
@SysLog
注解,配置描述参数
import java.lang.annotation.*;
/**
* Created by wangl on 2018/1/13.
* todo:
* 类SysLog的功能描述:
* 系统日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value() default "";
}
- 添加aop拦截器
- 新建一个类,在类上添加注解
@Aspect
,@Order(5)
(这里数字代表如果有多个拦截器,越小越优先执行),@Component
- 添加切点方法,这里直接指向我们之前新增的注解方法
@Pointcut("@annotation(com.mysiteforme.admin.annotation.SysLog)")
public void webLog(){}
- 添加前置通知(
我这里还记录了一些其他的信息)
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
startTime.set(System.currentTimeMillis());
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
HttpSession session = (HttpSession) attributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
sysLog = new Log();
sysLog.setClassMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
sysLog.setHttpMethod(request.getMethod());
//获取传入目标方法的参数
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
Object o = args[i];
if(o instanceof ServletRequest || (o instanceof ServletResponse) || o instanceof MultipartFile){
args[i] = o.toString();
}
}
String str = JSONObject.toJSONString(args);
sysLog.setParams(str.length()>5000?JSONObject.toJSONString("请求参数数据过长不与显示"):str);
String ip = ToolUtil.getClientIp(request);
if("0.0.0.0".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip) || "localhost".equals(ip) || "127.0.0.1".equals(ip)){
ip = "127.0.0.1";
}
sysLog.setRemoteAddr(ip);
sysLog.setRequestUri(request.getRequestURL().toString());
if(session != null){
sysLog.setSessionId(session.getId());
}
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
com.mysiteforme.admin.annotation.SysLog mylog = method.getAnnotation(com.mysiteforme.admin.annotation.SysLog.class);
if(mylog != null){
//<font color="red">注解上的描述</font>
sysLog.setTitle(mylog.value());
}
Map<String,String> browserMap = ToolUtil.getOsAndBrowserInfo(request);
sysLog.setBrowser(browserMap.get("os")+"-"+browserMap.get("browser"));
if(!"127.0.0.1".equals(ip)){
Map<String,String> map = ToolUtil.getAddressByIP(ToolUtil.getClientIp(request));
sysLog.setArea(map.get("area"));
sysLog.setProvince(map.get("province"));
sysLog.setCity(map.get("city"));
sysLog.setIsp(map.get("isp"));
}
sysLog.setType(ToolUtil.isAjax(request)?"Ajax请求":"普通请求");
if(MySysUser.ShiroUser() != null) {
sysLog.setUsername(StringUtils.isNotBlank(MySysUser.nickName()) ? MySysUser.nickName() : MySysUser.loginName());
}
}
主要是这段
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
com.mysiteforme.admin.annotation.SysLog mylog = method.getAnnotation(com.mysiteforme.admin.annotation.SysLog.class);
if(mylog != null){
//注解上的描述
sysLog.setTitle(mylog.value());
}
环绕通知 @Around("webLog()")
后置通知 @AfterReturning(returning = "ret", pointcut = "webLog()")
用法:
在需要健康的controller中的某个具体的方法上添加注解
@SysLog("跳转博客内容列表")
里面填写方法描述内容