最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA實(shí)現(xiàn)通用日志記錄方法

 更新時間:2017年06月05日 16:15:24   作者:God_Ming  
本篇文章主要介紹了JAVA實(shí)現(xiàn)通用日志記錄方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言:

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

于是還是準(zhǔn)備用通用的方法:controller層aop進(jìn)行切面記錄日志。

使用Aop記錄操作日志

第一步:添加Aop

/**
 * 統(tǒng)一日志處理Handler
 * @author Mingchenchen
 *
 */
public class LogAopHandler {
  @Autowired
  private AuditLogDao auditLogDao;

  /**
   * controller層面記錄操作日志
   * 注意此處是aop:around的 因?yàn)樾枰玫秸埱笄暗膮?shù)以及請求后接口返回的結(jié)果
   * @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接口參數(shù)為空 比如刪除XXX
        }else if (object instanceof String) {
          requestBody = (String) object;//有些接口直接把參數(shù)轉(zhuǎn)換成對象了
        }else {
          requestBody = JSONObject.toJSONString(object);
        }
      }
    }

    //只記錄POST方法的日志
    boolean isNeedSaveLog = false;
    //此處不能用getAnnotationByType 是JAVA8的特性,因?yàn)樽⒔饽軌蛑孛?所以得到的是數(shù)組
    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的參數(shù)后讓方法執(zhí)行它 
    //注意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中聲明

  <!-- 記錄操作日志 -->
  <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

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;
  }
}

第四步:根據(jù)Controller的方法名稱定制響應(yīng)的事件類型

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;//保存到數(shù)據(jù)庫的事件類型
  private String description;//保存到數(shù)據(jù)庫的描述
  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;
  }

  /**
   * 根據(jù)方法名返回
   * @param methodName
   * @return
   */
  public static LogTypeEnum getDesByMethodName(String methodName){
    return innerMap.map.get(methodName);
  }

  /**
   * 內(nèi)部類 用戶保存所有的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);
      }
    }
  }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java實(shí)現(xiàn)簡單聊天室單人版

    java實(shí)現(xiàn)簡單聊天室單人版

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡單聊天室的單人版,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Java中輸入單個char類型的字符方式

    Java中輸入單個char類型的字符方式

    這篇文章主要介紹了Java中輸入單個char類型的字符方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Java線程池?ThreadPoolExecutor?詳解

    Java線程池?ThreadPoolExecutor?詳解

    這篇文章主要介紹了Java線程池?ThreadPoolExecutor,線程池包括線程集合、阻塞隊(duì)列、拒絕策略處理器,更多相關(guān)內(nèi)容需要的朋友可以參考一下
    2022-07-07
  • 解析Java中的Field類和Method類

    解析Java中的Field類和Method類

    這篇文章主要介紹了Java中的Field類和Method類,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-12-12
  • java 反射 動態(tài)調(diào)用不同類的靜態(tài)方法(推薦)

    java 反射 動態(tài)調(diào)用不同類的靜態(tài)方法(推薦)

    下面小編就為大家?guī)硪黄狫AVA 反射 動態(tài)調(diào)用不同類的靜態(tài)方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • 超詳細(xì)的Intellij IDEA 看源碼必備技能

    超詳細(xì)的Intellij IDEA 看源碼必備技能

    這篇文章主要介紹了Intellij IDEA 看源碼必備技能,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • 解決idea2020.2遇到pom.xml文件報錯maven插件tomcat7的問題

    解決idea2020.2遇到pom.xml文件報錯maven插件tomcat7的問題

    這篇文章主要介紹了idea2020.2遇到pom.xml文件報錯maven插件tomcat7的問題,本文給大家分享解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • 劍指Offer之Java算法習(xí)題精講數(shù)組與二叉樹

    劍指Offer之Java算法習(xí)題精講數(shù)組與二叉樹

    跟著思路走,之后從簡單題入手,反復(fù)去看,做過之后可能會忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • Java源碼解析之GenericDeclaration詳解

    Java源碼解析之GenericDeclaration詳解

    這篇文章主要介紹了Java源碼解析之GenericDeclaration詳解。有句古話說得好,源碼能使人快樂!這里分享給大家,供需要的朋友參考。
    2017-10-10
  • JAVA生成pdf文件的實(shí)操教程

    JAVA生成pdf文件的實(shí)操教程

    PDF是可移植文檔格式,是一種電子文件格式,具有許多其他電子文檔格式無法相比的優(yōu)點(diǎn),下面這篇文章主要給大家介紹了關(guān)于JAVA生成pdf文件的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11

最新評論

青冈县| 中方县| 长泰县| 苗栗市| 洛隆县| 南溪县| 虞城县| 陈巴尔虎旗| 雅安市| 麻栗坡县| 宝坻区| 茂名市| 吉木萨尔县| 安宁市| 三江| 兴隆县| 长顺县| 双牌县| 炎陵县| 英德市| 阳西县| 呈贡县| 如皋市| 龙海市| 昌江| 长兴县| 英吉沙县| 阳山县| 湟源县| 离岛区| 武强县| 平定县| 杭州市| 泌阳县| 顺义区| 临漳县| 斗六市| 成安县| 盐津县| 北海市| 新兴县|