服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Spring MVC打印@RequestBody、@Response日志的方法

Spring MVC打印@RequestBody、@Response日志的方法

2021-07-14 15:29天啦撸 Java教程

这篇文章主要介绍了Spring MVC打印@RequestBody、@Response日志的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

问题描述:

使用json接收前端参数时, springmvc默认输出日志如下:

o.s.web.servlet.dispatcherservlet : post "/example_project/app/login", parameters={}
parameters={}无法打印出json消息内容。

如果自己实现参数打印, 则需要从reqeust.getinputstream中获取json内容, 但是由于流只能读取一次, 所以会导致后续springmvc解析参数异常。

网上找到一种比较解决方法: 用httprequestwrapper重新封装reqeust, 使打印日志后springmvc能正常解析httpreqeust。这种方法比较麻烦, 这里不去研究

这里主要说说spring提供的较好的解决方案:

可以通过自定义requestbodyadvisor、responsebodyadvisor来实现日志输出。

  • requestbodyadvisor可以获取到解析后的controller方法参数对象。
  • responsebodyadvisor可以获取到controller方法返回值对象。

然后将他们注册到requestmappinghandleradapter:

?
1
2
3
4
5
6
7
8
9
// 继承webmvcconfigurationsupport, 重写该方法
@override
@bean
public requestmappinghandleradapter requestmappinghandleradapter() {
  requestmappinghandleradapter adapter = super.requestmappinghandleradapter();
  adapter.setrequestbodyadvice(lists.newarraylist(new customerrequestbodyadvisor()));
  adapter.setresponsebodyadvice(lists.newarraylist(new customerresponsebodyadvisor()));
  return adapter;
}

另附customerrequestbodyadvisor、customerresponsebodyadvisor日志输出实现参考:

requestbodyadvisor实现参考:

?
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
// customerrequestbodyadvisor.java
/**
* 打印请求参数日志
*/
public class customerrequestbodyadvisor extends requestbodyadviceadapter {
 
  private static final logger logger = loggerfactory.getlogger(customerrequestbodyadvisor.class);
 
  @override
  public boolean supports(methodparameter methodparameter, type targettype, class<? extends httpmessageconverter<?>> convertertype) {
    // 只处理@requestbody注解了的参数
    return methodparameter.getparameterannotation(requestbody.class) != null;
  }
 
  @override
  public object afterbodyread(object body, httpinputmessage inputmessage, methodparameter parameter, type targettype, class<? extends httpmessageconverter<?>> convertertype) {
    method method = parameter.getmethod();
    
    // 参数对象转json字符串
    string jsonbody;
    if (stringhttpmessageconverter.class.isassignablefrom(convertertype)) {
      jsonbody = body.tostring();
    } else {
      jsonbody = json.tojsonstring(body, serializerfeature.usesinglequotes);
    }
    
    // 自定义日志输出
    if (logger.isinfoenabled()) {
      logger.info("{}#{}: {}", parameter.getcontainingclass().getsimplename(), method.getname(), jsonbody);
      //      logger.info("json request<=========method:{}#{}", parameter.getcontainingclass().getsimplename(), method.getname());
    }
    return super.afterbodyread(body, inputmessage, parameter, targettype, convertertype);
  }
}

responsebodyadvisor实现参考:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// customerresponsebodyadvisor.java
/**
* 打印响应值日志
*/
public class customerresponsebodyadvisor implements responsebodyadvice<object> {
  private static final logger logger = loggerfactory.getlogger(customerresponsebodyadvisor.class);
 
  @override
  public boolean supports(methodparameter returntype, class<? extends httpmessageconverter<?>> convertertype) {
    return abstractjackson2httpmessageconverter.class.isassignablefrom(convertertype)
        || returntype.getmethod().isannotationpresent(responsebody.class);
  }
 
  @override
  public object beforebodywrite(object body, methodparameter returntype, mediatype selectedcontenttype, class<? extends httpmessageconverter<?>> selectedconvertertype, serverhttprequest request, serverhttpresponse response) {
    // 响应值转json串输出到日志系统
    if (logger.isinfoenabled()) {
      logger.info("{}: {}", request.geturi(), json.tojsonstring(body, serializerfeature.usesinglequotes));
    }
    return body;
  }
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://segmentfault.com/a/1190000018085100

延伸 · 阅读

精彩推荐