好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

查看更多关于Spring MVC打印@RequestBody、@Response日志的方法的详细内容...

  阅读:17次