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

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

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

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

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 东北疯狂xxxxbbbb中国 | 久久国产精品高清一区二区三区 | 国产资源免费观看 | 日韩成人影视 | 久久精品一卡二卡三卡四卡视频版 | 天堂在线免费观看 | 男女羞羞的视频 | 999jjj在线播放 | 国产精品久久一区 | 色帽子影院 | 男女污网站| 99热精品成人免费观看 | 秒播影视 午夜福利毛片 | 久久艹影院 | 美女插插视频 | 猫影视tv接口 | 色戒完整版 | 久久久精品国产免费A片胖妇女 | 亚洲国产一区 | gay帅老头毛都白了 gayxxx视频 | 国产aⅴ一区二区三区 | 成人影院视频 | 免费刷10000名片赞网站 | 色人阁小说 | 卫生间被教官做好爽HH视频 | 精品精品国产自在现拍 | 三级午夜宅宅伦不卡在线 | 亚洲 日韩 在线 国产 视频 | tiny4k欧美极品在线 | 视频在线观看一区二区三区 | 日本激情在线 | 亚洲精品一区制服丝袜 | 国产专区日韩精品欧美色 | 波多野结衣在线观看视频 | 国产一区二区三区免费在线视频 | 欧美一区二区三区视视频 | 99精品国产成人一区二区在线 | aaaa黄色片 | 亚洲精品国产在线 | 98色花堂永久地址国产精品 | 欧美一级鲁丝片免费看 |