栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA实现通用日志记录方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA实现通用日志记录方法

前言:

之前想在filter层直接过滤httpServerletRequest请求进行日志处理,但是之后再getWriter()的 时候报already been call异常。查了下,才发现原来流形式的只能读取一次。。就好像食物,吃了就没了。。 所以在filter和inteceptor里面是没法通过获取request的流来进行日志记录的。

于是还是准备用通用的方法:controller层aop进行切面记录日志。

使用Aop记录操作日志

第一步:添加Aop


public class LogAopHandler {
  @Autowired
  private AuditLogDao auditLogDao;

  
  public Object doSaveLog(ProceedingJoinPoint joinPoint) throws Throwable { 
    MethodSignature method = (MethodSignature) joinPoint.getSignature();
    String methodName = method.getName();
    Object[] objects = joinPoint.getArgs();
    String requestBody = null;
    if (objects!=null && objects.length>0) {
      for (Object object : objects) {
 if (object == null) {
   requestBody = null;//POST接口参数为空 比如删除XXX
 }else if (object instanceof String) {
   requestBody = (String) object;//有些接口直接把参数转换成对象了
 }else {
   requestBody = JSONObject.toJSonString(object);
 }
      }
    }

    //只记录POST方法的日志
    boolean isNeedSaveLog = false;
    //此处不能用getAnnotationByType 是JAVA8的特性,因为注解能够重名,所以得到的是数组
    RequestMapping annotation = method.getMethod().getAnnotation(RequestMapping.class);
    for (RequestMethod requestMethod : annotation.method()) {
      if (requestMethod==RequestMethod.POST) {
 isNeedSaveLog = true;
      }
    }

    JSonObject requestBodyJson = null;
    try {
      requestBodyJson = JSONObject.parseObject(requestBody);
    } catch (Exception e) {
      //do nothing 即POST请求没传body
    }
    HttpServletRequest request = RequestContextUtil.getRequestByCurrentContext();
    String userName = RequestContextUtil.getUserNameByCurrentContext();
    if (StringUtil.isEmpty(userName)) {
      try {
 userName = DmsCache.get(requestBodyJson.getString("userName")).getName();
      } catch (Exception e) {
 userName = RequestContextUtil.getAsynUserInfoByAutoDeploy().getName();
      }
    }

    //得到request的参数后让方法执行它 
    //注意around的情况下需要返回result 否则将不会返回值给请求者
    Object result = joinPoint.proceed(objects);
    try {
      JSonObject resultJson = JSONObject.parseObject(result.toString());
      if (isNeedSaveLog) {//如果是POST请求 则记录日志
 LogTypeEnum logTypeEnum = LogTypeEnum.getDesByMethodName(methodName);
 if (logTypeEnum != null) {
   AuditLogEntity auditLogEntity = new AuditLogEntity();
   auditLogEntity.setUuid(StringUtil.createRandomUuid());
   auditLogEntity.setOperator(userName);
   auditLogEntity.setRequestIp(request.getRemoteAddr());
   auditLogEntity.setRequestUrl(request.getRequestURI().replace("/cloud-master", ""));
   auditLogEntity.setEventType(logTypeEnum.getKey());
   auditLogEntity.setEventDesc(logTypeEnum.getDescription());
   auditLogEntity.setRequest(requestBody);
   int isSuccess = "200".equals(resultJson.getString("code")) ? 1 : 0;
   auditLogEntity.setSuccessFlag(isSuccess);
   auditLogEntity.setResponse(result.toString());
   auditLogEntity.setCreateTime(new Date());
   auditLogDao.insert(auditLogEntity);
 }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  } 
}

第二步:在spring的xml中声明

  
  
   
    
     
     
    
   

如此一来,核心步骤就完成了,剩下的就是自己组装需要记录的东西了。

第三步:写Dao、Entity、Mapper

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;


@Table(name="audit_log")
public class AuditLogEntity {
  @Id
  private String uuid;

  @Column(name="event_type")
  private String eventType;//事件类型

  @Column(name="event_desc")
  private String eventDesc;//事件中文描述

  @Column(name="operator")
  private String operator;//操作者

  @Column(name="request_ip")
  private String requestIp;//客户端地址

  @Column(name="request_url")
  private String requestUrl;//请求地址

  @Column(name="request")
  private String request;//请求body

  @Column(name="response")
  private String response;//请求返回值

  @Column(name="create_time")
  private Date createTime;

  public String getUuid() {
    return uuid;
  }

  public void setUuid(String uuid) {
    this.uuid = uuid;
  }

  public String getEventType() {
    return eventType;
  }

  public void setEventType(String eventType) {
    this.eventType = eventType;
  }

  public String getEventDesc() {
    return eventDesc;
  }

  public void setEventDesc(String eventDesc) {
    this.eventDesc = eventDesc;
  }

  public String getOperator() {
    return operator;
  }

  public void setOperator(String operator) {
    this.operator = operator;
  }

  public String getRequestIp() {
    return requestIp;
  }

  public void setRequestIp(String requestIp) {
    this.requestIp = requestIp;
  }

  public String getRequestUrl() {
    return requestUrl;
  }

  public void setRequestUrl(String requestUrl) {
    this.requestUrl = requestUrl;
  }

  public String getRequest() {
    return request;
  }

  public void setRequest(String request) {
    this.request = request;
  }

  public String getResponse() {
    return response;
  }

  public void setResponse(String response) {
    this.response = response;
  }

  public Date getCreateTime() {
    return createTime;
  }

  public void setCreateTime(Date createTime) {
    this.createTime = createTime;
  }
}

第四步:根据Controller的方法名称定制响应的事件类型

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public enum LogTypeEnum {
  //用户
  COMMON_LOGIN("login","login","登录");
  //其他

  private String methodName;//方法名称与controller一致
  private String key;//保存到数据库的事件类型
  private String description;//保存到数据库的描述
  private LogTypeEnum(String methodName,String key,String description){
    this.methodName = methodName;
    this.key = key;
    this.description = description;
  }
  public String getMethodName() {
    return methodName;
  }
  public void setMethodName(String methodName) {
    this.methodName = methodName;
  }
  public String getKey() {
    return key;
  }
  public void setKey(String key) {
    this.key = key;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }

  
  public static LogTypeEnum getDesByMethodName(String methodName){
    return innerMap.map.get(methodName);
  }

  
  private static class innerMap{
    private static Map map = new ConcurrentHashMap<>(128);

    static{
      //初始化整个枚举类到Map
      for (LogTypeEnum logTypeEnum : LogTypeEnum.values()) {
 map.put(logTypeEnum.getMethodName(), logTypeEnum);
      }
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/145794.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号