问题描述:
使用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