国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務(wù)器之家 - 編程語言 - Java教程 - SpringBoot記錄Http請求日志的方法

SpringBoot記錄Http請求日志的方法

2021-07-22 16:26Simeone_xu Java教程

這篇文章主要介紹了SpringBoot記錄Http請求日志的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

在使用spring boot開發(fā) web api 的時候希望把 request,request header ,response reponse header , uri, method 等等的信息記錄到我們的日志中,方便我們排查問題,也能對系統(tǒng)的數(shù)據(jù)做一些統(tǒng)計。

spring 使用了 dispatcherservlet 來攔截并分發(fā)請求,我們只要自己實現(xiàn)一個 dispatcherservlet 并在其中對請求和響應(yīng)做處理打印到日志中即可。

我們實現(xiàn)一個自己的分發(fā) servlet ,它繼承于 dispatcherservlet,我們實現(xiàn)自己的 dodispatch(httpservletrequest request, httpservletresponse response) 方法。

?
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
public class loggabledispatcherservlet extends dispatcherservlet {
 
  private static final logger logger = loggerfactory.getlogger("httplogger");
 
  private static final objectmapper mapper = new objectmapper();
 
  @override
  protected void dodispatch(httpservletrequest request, httpservletresponse response) throws exception {
    contentcachingrequestwrapper requestwrapper = new contentcachingrequestwrapper(request);
    contentcachingresponsewrapper responsewrapper = new contentcachingresponsewrapper(response);
    //創(chuàng)建一個 json 對象,用來存放 http 日志信息
    objectnode rootnode = mapper.createobjectnode();
    rootnode.put("uri", requestwrapper.getrequesturi());
    rootnode.put("clientip", requestwrapper.getremoteaddr());
    rootnode.set("requestheaders", mapper.valuetotree(getrequestheaders(requestwrapper)));
    string method = requestwrapper.getmethod();
    rootnode.put("method", method);
    try {
      super.dodispatch(requestwrapper, responsewrapper);
    } finally {
      if(method.equals("get")) {
        rootnode.set("request", mapper.valuetotree(requestwrapper.getparametermap()));
      } else {
        jsonnode newnode = mapper.readtree(requestwrapper.getcontentasbytearray());
        rootnode.set("request", newnode);
      }
 
      rootnode.put("status", responsewrapper.getstatus());
      jsonnode newnode = mapper.readtree(responsewrapper.getcontentasbytearray());
      rootnode.set("response", newnode);
 
      responsewrapper.copybodytoresponse();
 
      rootnode.set("responseheaders", mapper.valuetotree(getresponsetheaders(responsewrapper)));
      logger.info(rootnode.tostring());
    }
  }
 
  private map<string, object> getrequestheaders(httpservletrequest request) {
    map<string, object> headers = new hashmap<>();
    enumeration<string> headernames = request.getheadernames();
    while (headernames.hasmoreelements()) {
      string headername = headernames.nextelement();
      headers.put(headername, request.getheader(headername));
    }
    return headers;
 
  }
 
  private map<string, object> getresponsetheaders(contentcachingresponsewrapper response) {
    map<string, object> headers = new hashmap<>();
    collection<string> headernames = response.getheadernames();
    for (string headername : headernames) {
      headers.put(headername, response.getheader(headername));
    }
    return headers;
  }

在 loggabledispatcherservlet 中,我們可以通過 httpservletrequest 中的 inputstream 或 reader 來獲取請求的數(shù)據(jù),但如果我們直接在這里讀取了流或內(nèi)容,到后面的邏輯將無法進行下去,所以需要實現(xiàn)一個可以緩存的 httpservletrequest。好在 spring 提供這樣的類,就是 contentcachingrequestwrapper 和 contentcachingresponsewrapper, 根據(jù)官方的文檔這兩個類正好是來干這個事情的,我們只要將 httpservletrequest 和 httpservletresponse 轉(zhuǎn)化即可。

httpservletrequest wrapper that caches all content read from the input stream and reader, and allows this content to be retrieved via a byte array.
used e.g. by abstractrequestloggingfilter. note: as of spring framework 5.0, this wrapper is built on the servlet 3.1 api.

httpservletresponse wrapper that caches all content written to the output stream and writer, and allows this content to be retrieved via a byte array.
used e.g. by shallowetagheaderfilter. note: as of spring framework 5.0, this wrapper is built on the servlet 3.1 api.

實現(xiàn)好我們的 loggabledispatcherservlet后,接下來就是要指定使用 loggabledispatcherservlet 來分發(fā)請求。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@springbootapplication
public class sbdemoapplication implements applicationrunner {
 
  public static void main(string[] args) {
    springapplication.run(sbdemoapplication.class, args);
  }
  @bean
  public servletregistrationbean dispatcherregistration() {
    return new servletregistrationbean(dispatcherservlet());
  }
  @bean(name = dispatcherservletautoconfiguration.default_dispatcher_servlet_bean_name)
  public dispatcherservlet dispatcherservlet() {
    return new loggabledispatcherservlet();
  }
}

增加一個簡單的 controller 來測試一下

?
1
2
3
4
5
6
7
8
9
@restcontroller
@requestmapping("/hello")
public class hellocontroller {
 
  @requestmapping(value = "/word", method = requestmethod.post)
  public object hello(@requestbody object object) {
    return object;
  }
}

使用 curl 發(fā)送一個 post 請求:

?
1
2
3
4
5
$ curl --header "content-type: application/json" \
 --request post \
 --data '{"username":"xyz","password":"xyz"}' \
 http://localhost:8080/hello/word
{"username":"xyz","password":"xyz"}

查看打印的日志:

?
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
{
  "uri":"/hello/word",
  "clientip":"0:0:0:0:0:0:0:1",
  "requestheaders":{
    "content-length":"35",
    "host":"localhost:8080",
    "content-type":"application/json",
    "user-agent":"curl/7.54.0",
    "accept":"*/*"
  },
  "method":"post",
  "request":{
    "username":"xyz",
    "password":"xyz"
  },
  "status":200,
  "response":{
    "username":"xyz",
    "password":"xyz"
  },
  "responseheaders":{
    "content-length":"35",
    "date":"sun, 17 mar 2019 08:56:50 gmt",
    "content-type":"application/json;charset=utf-8"
  }
}

當(dāng)然打印出來是在一行中的,我進行了一下格式化。我們還可以在日志中增加請求的時間,耗費的時間以及異常信息等。

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

原文鏈接:https://segmentfault.com/a/1190000018535456

延伸 · 閱讀

精彩推薦
  • Java教程Java內(nèi)存模型知識詳解

    Java內(nèi)存模型知識詳解

    這篇文章主要介紹了Java內(nèi)存模型知識詳解,文中通過對內(nèi)存訪問時的交互關(guān)系圖解介紹的十分詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要...

    殘雪余香4022020-08-01
  • Java教程詳解Java設(shè)計模式編程中的中介者模式

    詳解Java設(shè)計模式編程中的中介者模式

    這篇文章主要介紹了Java設(shè)計模式編程中的中介者模式,文中舉了典型的同事類與中介者類的例子來解釋說明,需要的朋友可以參考下 ...

    卡奴達摩4862020-03-28
  • Java教程java web項目實現(xiàn)文件下載實例代碼

    java web項目實現(xiàn)文件下載實例代碼

    現(xiàn)在項目里面有個需求,需要把系統(tǒng)產(chǎn)生的日志文件給下載到本地 先獲取所有的日志文件列表,顯示到界面,選擇一個日志文件,把文件名傳到后臺 ...

    java代碼網(wǎng)3012019-10-15
  • Java教程IntelliJ IDEA修改內(nèi)存大小,使得idea運行更流暢

    IntelliJ IDEA修改內(nèi)存大小,使得idea運行更流暢

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA修改內(nèi)存大小,使得idea運行更流暢的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要...

    李學(xué)凱6002021-06-06
  • Java教程Java 獲取泛型的類型實例詳解

    Java 獲取泛型的類型實例詳解

    這篇文章主要介紹了Java 獲取泛型的類型實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下...

    IamOkay3842020-10-30
  • Java教程詳解在Spring中如何使用AspectJ來實現(xiàn)AOP

    詳解在Spring中如何使用AspectJ來實現(xiàn)AOP

    這篇文章主要介紹了詳解在Spring中如何使用AspectJ來實現(xiàn)AOP,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    deniro5132021-05-12
  • Java教程詳解Java項目中讀取properties文件

    詳解Java項目中讀取properties文件

    本篇文章主要介紹了Java項目中讀取properties文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下。...

    lanchengxiaoxiao5392020-07-19
  • Java教程java更改圖片大小示例分享

    java更改圖片大小示例分享

    這篇文章主要介紹了java更改圖片大小示例,方法中指定路徑 ,舊文件名稱 ,新文件名稱,n 改變倍數(shù)就可以完成更改圖片大小,需要的朋友可以參考下 ...

    java教程網(wǎng)1942019-11-13
主站蜘蛛池模板: 日韩av在线一区 | 免费日韩成人 | 日本不卡一二三区 | 国产精品3区 | 国产精品中文字幕在线 | 交视频在线观看国产 | 精品黄色在线观看 | 亚洲国产精品视频 | 久久久久中文字幕 | 国产脚交av在线一区二区 | 天天干天天射天天操 | 久久久亚洲综合 | 亚洲高清在线视频 | 国产精品第十页 | 天天插天天操 | 亚洲综合色自拍一区 | 欧美一区二区三区男人的天堂 | 亚洲九九 | 欧美亚洲视频在线观看 | 久久综合久色欧美综合狠狠 | 精品网站www | 美女视频黄色 | 亚洲精品国产第一综合99久久 | 国产资源大全 | 国产福利精品一区 | 亚洲一区二区精品在线观看 | 91精品国产欧美一区二区成人 | 亚洲成人三级 | 国产亚洲精品久久久久动 | 黄色小视频在线 | 精品视频在线免费观看 | 国产精品视频区 | 亚洲av毛片一区二二区三三区 | 在线观看视频91 | 日韩中文视频 | 北条麻妃99精品青青久久 | 95香蕉视频 | 中文字幕乱码亚洲精品一区 | 蜜桃av网址| 精品国产精品三级精品av网址 | 99久久婷婷国产综合精品电影 |