問(wèn)題描述:
使用json接收前端參數(shù)時(shí), springmvc默認(rèn)輸出日志如下:
o.s.web.servlet.dispatcherservlet : post "/example_project/app/login", parameters={}
parameters={}無(wú)法打印出json消息內(nèi)容。
如果自己實(shí)現(xiàn)參數(shù)打印, 則需要從reqeust.getinputstream中獲取json內(nèi)容, 但是由于流只能讀取一次, 所以會(huì)導(dǎo)致后續(xù)springmvc解析參數(shù)異常。
網(wǎng)上找到一種比較解決方法: 用httprequestwrapper重新封裝reqeust, 使打印日志后springmvc能正常解析httpreqeust。這種方法比較麻煩, 這里不去研究
這里主要說(shuō)說(shuō)spring提供的較好的解決方案:
可以通過(guò)自定義requestbodyadvisor、responsebodyadvisor來(lái)實(shí)現(xiàn)日志輸出。
- requestbodyadvisor可以獲取到解析后的controller方法參數(shù)對(duì)象。
- responsebodyadvisor可以獲取到controller方法返回值對(duì)象。
然后將他們注冊(cè)到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日志輸出實(shí)現(xiàn)參考:
requestbodyadvisor實(shí)現(xiàn)參考:
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 /** * 打印請(qǐng)求參數(shù)日志 */ 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注解了的參數(shù) 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(); // 參數(shù)對(duì)象轉(zhuǎn)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實(shí)現(xiàn)參考:
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 /** * 打印響應(yīng)值日志 */ 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) { // 響應(yīng)值轉(zhuǎn)json串輸出到日志系統(tǒng) if (logger.isinfoenabled()) { logger.info( "{}: {}" , request.geturi(), json.tojsonstring(body, serializerfeature.usesinglequotes)); } return body; } } |
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://segmentfault.com/a/1190000018085100