一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|

服務器之家 - 編程語言 - JAVA教程 - JAVA實現通用日志記錄方法

JAVA實現通用日志記錄方法

2020-11-09 15:38God_Ming JAVA教程

本篇文章主要介紹了JAVA實現通用日志記錄方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言:

之前想在filter層直接過濾httpServerletRequest請求進行日志處理,但是之后再getWriter()的 時候報already been call異常。查了下,才發現原來流形式的只能讀取一次。。就好像食物,吃了就沒了。。 所以在filter和inteceptor里面是沒法通過獲取request的流來進行日志記錄的。

于是還是準備用通用的方法:controller層aop進行切面記錄日志。

使用Aop記錄操作日志

第一步:添加Aop

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
 * 統一日志處理Handler
 * @author Mingchenchen
 *
 */
public class LogAopHandler {
  @Autowired
  private AuditLogDao auditLogDao;
 
  /**
   * controller層面記錄操作日志
   * 注意此處是aop:around的 因為需要得到請求前的參數以及請求后接口返回的結果
   * @throws Throwable
   */
  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中聲明

?
1
2
3
4
5
6
7
8
<!-- 記錄操作日志 -->
<bean id="operationLogAop" class="com.ming.learn.core.aop.LogAopHandler"/>
 <aop:config>
  <aop:aspect id="logAOP" ref="operationLogAop">
   <aop:pointcut id="target" expression="execution(* com.ming.learn..*Controller.*(..))"/>
   <aop:around method="doSaveLog" pointcut-ref="target"/>
  </aop:aspect>
 </aop:config>

如此一來,核心步驟就完成了,剩下的就是自己組裝需要記錄的東西了。

第三步:寫Dao、Entity、Mapper

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import java.util.Date;
 
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
 
/**
 * 日志審計
 * @author Mingchenchen
 *
 */
@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的方法名稱定制響應的事件類型

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * 操作日志類型
 * @author Mingchenchen
 *
 */
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;
  }
 
  /**
   * 根據方法名返回
   * @param methodName
   * @return
   */
  public static LogTypeEnum getDesByMethodName(String methodName){
    return innerMap.map.get(methodName);
  }
 
  /**
   * 內部類 用戶保存所有的enum 無須通過Enum.values()每次遍歷
   * @author Mingchenchen
   *
   */
  private static class innerMap{
    private static Map<String, LogTypeEnum> map = new ConcurrentHashMap<>(128);
 
    static{
      //初始化整個枚舉類到Map
      for (LogTypeEnum logTypeEnum : LogTypeEnum.values()) {
        map.put(logTypeEnum.getMethodName(), logTypeEnum);
      }
    }
  }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/jinzhencs/article/details/51882751

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品一卡二卡三卡四卡视频版 | 欧美伊香蕉久久综合类网站 | 国产清纯白嫩大学生正在播放 | 国产日韩欧美一区 | 国产一级毛片外aaaa | 精品一区二区高清在线观看 | 五月天导航 | 人妇小说 | 美味情缘韩国在线观看视频 | 西西人体大胆啪啪私拍色约约 | 欧美第十页 | 亚洲国产三级在线观看 | 日韩中文字幕在线不卡 | 亚洲国产成人在人网站天堂 | 日本伊人色 | 99re8在这里只有精品2 | 欧美日韩国产亚洲一区二区三区 | 四虎影院在线免费播放 | 久九九精品免费视频 | 暖暖的视频完整视频韩国免费 | 亚洲视频免 | 国产欧美成人免费观看 | 夫妇野外交换激情 | 九色PORNY丨视频入口 | 国产一卡2卡3卡四卡高清 | 国产一级免费片 | 9久热这里只有精品视频在线观看 | 国色天香社区视频免费观看3 | 午夜影院小视频 | www.久久av.com| se婷婷| 亚洲精品国产成人中文 | 蜜桃视频一区二区三区四区 | 99色在线播放 | 国产思妍小仙女一二区 | 暖暖中国免费观看高清完整版 | 色综七七久久成人影 | 三上悠亚久久国产 | 日本一道本中文字幕 | chinese国产人妖hd| 99精品在线免费观看 |