升級(jí)SpringBoot版本,引出了一個(gè)大Bug
前言
最近項(xiàng)目組升級(jí)了SpringBoot?版本,由之前的2.0.4?升級(jí)到最新版本2.7.5,卻引出了一個(gè)大Bug。
到底是怎么回事呢?
1、案發(fā)現(xiàn)場(chǎng)
有一天,項(xiàng)目組的同事反饋給我說(shuō),我之前有個(gè)接口在新的測(cè)試環(huán)境報(bào)錯(cuò)了,具體異常是:Missing argment level for method parameter of type Integer。
我當(dāng)時(shí)的第一反應(yīng)有點(diǎn)懵,心想這個(gè)接口是一個(gè)老接口,有一年多的時(shí)間都沒(méi)改過(guò)了,怎么會(huì)出問(wèn)題呢?
他說(shuō)近期另外一個(gè)同事為了部署阿里云服務(wù)器?,把新測(cè)試環(huán)境SpringBoot?的版本升級(jí)到了最新版。
之后,在測(cè)試的過(guò)程中,發(fā)現(xiàn)我有個(gè)Get請(qǐng)求接口報(bào)異常了。
該接口代碼類(lèi)似于這樣:?在getCategory接口中,有兩個(gè)參數(shù):
- type表示大類(lèi),是必傳的。
- level表示要返回幾級(jí)分類(lèi),比如:4級(jí)分類(lèi),就傳4,是非必傳的,默認(rèn)就是查4級(jí)分類(lèi)。
就是這樣一個(gè)接口的level參數(shù),前端沒(méi)有傳參,例如:
結(jié)果被Spring MVC攔截直接報(bào)錯(cuò)了。
2、報(bào)錯(cuò)的原因
從打印的異常信息看,現(xiàn)在level參數(shù)必須要傳值了,之前是可傳,可不傳的。
我后來(lái)本打算自定義Spring的轉(zhuǎn)換器,修改一下校驗(yàn)規(guī)則,跟老版本保持一致。
這樣那些基本接口就不用改了。
但后來(lái)發(fā)現(xiàn),被spring-web-5.3.23的源碼無(wú)情的打臉了。
在org.springframework.web.method.annotation?包下的AbstractNamedValueMethodArgumentResolver?類(lèi)的resolveArgument?方法中:多了這樣的校驗(yàn)。如果該參數(shù)為空,沒(méi)有設(shè)置默認(rèn)值,required屬性為true,并且不是Optional類(lèi)型,則執(zhí)行handleMissingValueAfterConversion?方法。該方法會(huì)調(diào)用handleMissingValue方法,具體代碼如圖中所示:最后會(huì)拋出之前我看到的那個(gè)異常。
原因最新版本的Spring中不允許Get接口的請(qǐng)求參數(shù),在不使用@RequestParam注解時(shí),值為空的情況出現(xiàn)了。
3、如何解決問(wèn)題?
想要解決上面的報(bào)錯(cuò)問(wèn)題,其實(shí)很簡(jiǎn)單,只需在level參數(shù)前加??@RequestParam?
??注解,并且設(shè)置??required?
??屬性為??false?
?。
例如:
但是后面發(fā)現(xiàn),項(xiàng)目中不只我這一個(gè)接口要調(diào)整,其他好多同事的接口,也有類(lèi)似的問(wèn)題,需要修改的接口很多。
這個(gè)改動(dòng)的工作量不小。
哭暈在測(cè)試。。。
后話
這個(gè)問(wèn)題有很多人中招,所以非常有必要把這個(gè)問(wèn)題分享給大家,防微杜漸。
我之前l(fā)evel參數(shù)不加@RequestParam?注解,也沒(méi)設(shè)置required?屬性,當(dāng)時(shí)持有的心態(tài)是Spring有默認(rèn)值,有些注解不加,程序也能正常運(yùn)行,既然這樣就可以少寫(xiě)點(diǎn)代碼,并且在當(dāng)時(shí)的版本測(cè)試過(guò),沒(méi)有出現(xiàn)過(guò)什么問(wèn)題。
這種情況其實(shí)是Spring框架的一個(gè)bug,已經(jīng)在最新版本中被修復(fù)了。。。
趕緊review一下你們的代碼,看看有沒(méi)有類(lèi)似的用法,不然遲早有一天也會(huì)中招。