源碼分析SpringMvc日志打印被忽略輸出問(wèn)題
1.寫在前面
在java的開發(fā)過(guò)程中,涉及到j(luò)ava web的開發(fā),基本上都是走spring這一套了。
我們之前一般來(lái)說(shuō),都會(huì)說(shuō)mvc:Model(模型業(yè)務(wù))、View(視圖界面)、Controller(控制器)。這個(gè)學(xué)習(xí)java開發(fā)的,應(yīng)該都懂吧,這里就不多說(shuō)了。
這里,我們先著重解析下Controller:
Controller控制器是指控制器接受用戶的輸入并調(diào)用模型和視圖去完成用戶的需求,控制器本身不輸出任何東西和做任何處理。它只是接收請(qǐng)求并決定調(diào)用哪個(gè)模型構(gòu)件去處理請(qǐng)求,然后再確定用哪個(gè)視圖來(lái)顯示返回的數(shù)據(jù)。
那作為控制層的框架,一般有springmvc、struts2,struts2一些老的框架可能會(huì)用到,新的一些框架,基本就很少見(jiàn)了,都走springmvc這套了。
springmvc,我們就用得多了,但是對(duì)于SpringMvc日志打印被忽略輸出的問(wèn)題,有無(wú)人研究過(guò)呢?
嘿嘿,巧了,這個(gè)問(wèn)題,哥們研究過(guò)了,那我們今天就來(lái)分析下這個(gè)問(wèn)題嘍?。?!
2.問(wèn)題引出
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor Read "application/json;charset=UTF-8" to [QueryData(pageNo=1, pageSize=10, sortField=, sortOrder=asc, params={Q_XM_S_EQ=llsydn, Q_SJH_S_EQ=135 (truncated)...]
可以看到控制臺(tái)打印的日志,出現(xiàn)了 (truncated)...
這里對(duì)應(yīng)的前端頁(yè)面的功能是這樣的:
很明顯,springmvc接收到前端傳進(jìn)來(lái)的參數(shù),然后會(huì)在控制臺(tái)打印相關(guān)的日志。但是這里的參數(shù),日志打印是不完整的。出現(xiàn)了 (truncated)...
截取的問(wèn)題。
看到這,有好奇心的小伙伴,估計(jì)都想探個(gè)究竟了吧?(別說(shuō)你不想??)
好嘛好嘛,是我自己想探個(gè)究竟啦?。?!(卑微)
那這里我們先從源碼中,找到被截取的地方嘍。
3.截取源碼分析
首先這里,要如何進(jìn)行源碼查看呢?這里我們可以從打印的日志入手......
- RequestResponseBodyMethodProcessor
進(jìn)入到RequestResponseBodyMethodProcessor類中,查看log打印日志的地方,并沒(méi)有發(fā)現(xiàn)打印日志的代碼。
那我們就將該類所有的方法都打上斷點(diǎn)(主要是該類不算很大),再發(fā)一個(gè)請(qǐng)求,斷點(diǎn)調(diào)試一下:
- 進(jìn)入到readWithMessageConverters,方法里面來(lái)了
經(jīng)過(guò)一步步執(zhí)行,執(zhí)行到
Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
可以看到控制臺(tái),就打印了我們剛才的日志
那這里,我們就可以繼續(xù)往readWithMessageConverters
,里面進(jìn)行查看(再發(fā)一個(gè)請(qǐng)求)
經(jīng)過(guò)一步步執(zhí)行,執(zhí)行到LogFormatUtils.traceDebug
可以看到控制臺(tái),就打印了我們剛才的日志
那這里,將其他的斷點(diǎn)去掉,再這里點(diǎn)一個(gè),然后再發(fā)一個(gè)請(qǐng)求進(jìn)來(lái)。
嘿嘿,看到這,估計(jì)大家都知道了吧。
當(dāng)參數(shù)字符超過(guò)100,這里就會(huì)截取。
看到這里,我們是通過(guò)源碼,一步步的找到最終的原因,那這里只是提供一個(gè)方法,思路。
大家伙可以自己動(dòng)手去調(diào)試一波,畢竟也不難,哈哈!
這里貼一下,最終的業(yè)務(wù)邏輯代碼,如下:
(limitLength && str.length() > 100 ? str.substring(0, 100) + " (truncated)..." : str);
可以看到,當(dāng)limitLength為true時(shí),str長(zhǎng)度大于100,就會(huì)截取前100個(gè)字符,后面再拼接 (truncated)...
那我們不禁會(huì)想,嘿,哥們想辦法把limitLength
的值,改為false,不就永遠(yuǎn)都不會(huì)截取輸出日志了嗎?
嗯嗯,是這么一回事,那這個(gè)limitLength
的值,如何改?怎么來(lái)的?
只能通過(guò)源碼分析一波了,好啦,這個(gè)任務(wù)就交給各位了,動(dòng)手去干活吧!
4.截取問(wèn)題處理
public boolean isTraceEnabled(Marker marker) { final FilterReply decision = callTurboFilters(marker, Level.TRACE); if (decision == FilterReply.NEUTRAL) { return effectiveLevelInt <= Level.TRACE_INT; } else if (decision == FilterReply.DENY) { return false; } else if (decision == FilterReply.ACCEPT) { return true; } else { throw new IllegalStateException("Unknown FilterReply value: " + decision); } }
通過(guò)查看這里的代碼,就是這里返回上面limitLength
的值。
可以看到這里,我們的改變decision
的值,讓它變成FilterReply.ACCEPT
,這樣這里就能返回true
了。
callTurboFilters,如何改呢?這里我百度找到了一個(gè)方式:
Logback 使用TurboFilter實(shí)現(xiàn)日志級(jí)別等內(nèi)容的動(dòng)態(tài)修改操作。
- 定義TurboFilter
public class SpringMvcFilter extends TurboFilter { @Override public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable throwable) { if (logger.getName().equals("org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor")) { return FilterReply.ACCEPT; //返回accept } return FilterReply.NEUTRAL; } }
- logback的配置xml
<configuration> <turboFilter class="com.llsydn.log.filter.SpringMvcFilter" /> ...... </configuration>
看看最終效果:
DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor Read "application/json;charset=UTF-8" to [QueryData(pageNo=1, pageSize=10, sortField=, sortOrder=asc, params={Q_XM_S_EQ=llsydn, Q_SJH_S_EQ=135****4606]
可以看到,springmvc打印的日志,正常了,不再截取了。
好了,以上就是 SpringMvc日志打印被忽略輸出問(wèn)題分析(源碼分析) 的分享了。
個(gè)人實(shí)操可能也不夠全面,班門弄斧了。
以上就是源碼分析SpringMvc日志打印被忽略輸出問(wèn)題的詳細(xì)內(nèi)容,更多關(guān)于SpringMvc日志打印被忽略輸出的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于Spring自定義XML schema 擴(kuò)展的問(wèn)題(Spring面試高頻題)
今天給大家分享一道spring高頻率面試題關(guān)于Spring自定義XML schema 擴(kuò)展的問(wèn)題,今天以spring整合dubbo的實(shí)例給大家詳細(xì)講解下,感興趣的朋友跟隨小編一起看看吧2021-05-05實(shí)例講解使用Spring通過(guò)JPA連接到Db2
這篇文章主要介紹了通過(guò)實(shí)例講解使用Spring通過(guò)JPA連接到Db2,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面我們來(lái)一起學(xué)習(xí)一下吧2019-06-06關(guān)于IDEA2020.1新建項(xiàng)目maven PKIX 報(bào)錯(cuò)問(wèn)題解決方法
這篇文章主要介紹了關(guān)于IDEA2020.1新建項(xiàng)目maven PKIX 報(bào)錯(cuò)問(wèn)題解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06修改idea運(yùn)行內(nèi)存大小的方法總結(jié)
在開發(fā)過(guò)程中,總會(huì)遇到idea運(yùn)行內(nèi)存不足,所以本文小編給大家介紹了修改idea運(yùn)行內(nèi)存大小的兩種方法,文中通過(guò)圖文給大家講解的非常詳細(xì),需要的朋友可以參考下2023-12-12解決springboot MultipartFile文件上傳遇到的問(wèn)題
本文給大家?guī)?lái)了解決springboot MultipartFile文件上傳遇到的問(wèn)題,解決方法超簡(jiǎn)單,感興趣的朋友參考下本文2018-08-08spring中的BeanFactory與FactoryBean的講解
今天小編就為大家分享一篇關(guān)于spring中的BeanFactory與FactoryBean的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01微服務(wù)中使用Maven BOM來(lái)管理你的版本依賴詳解
這篇文章主要介紹了微服務(wù)中使用Maven BOM來(lái)管理你的版本依賴,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12