時(shí)間有些緊迫拣宏,所以文中有些待考證的地方還未進(jìn)行測(cè)驗(yàn)深究缀拭,大家見(jiàn)諒织阳。
自己造算是了個(gè)輪子眶蕉,個(gè)人感覺(jué)這個(gè)輪子以后很多地方都會(huì)用到的吧。
需求起因:
這兩天剛開(kāi)始寫SpringBoot唧躲,用到了JPA的東西造挽,然后對(duì)于后端處理業(yè)務(wù)比較重要的一塊就是參數(shù)的校驗(yàn)。個(gè)人目前看來(lái)校驗(yàn)分兩類弄痹,第一類是類似Validator的東西饭入,就是根據(jù)輸入的參數(shù)直接在實(shí)體上設(shè)定好規(guī)則,然后傳入?yún)?shù)的時(shí)候進(jìn)行檢驗(yàn)合理性肛真,比如NotNull(目前僅用到了于javax包下的validation里面的那些constraints)谐丢,出現(xiàn)異常就拋出。第二類就是涉及到數(shù)據(jù)庫(kù)的一種校驗(yàn)毁欣,比如Unique校驗(yàn)庇谆,據(jù)我目前所知好像hibernate本身是沒(méi)有替我們進(jìn)行數(shù)據(jù)庫(kù)比對(duì),所以涉及到數(shù)據(jù)庫(kù)中的校驗(yàn)就需要自己來(lái)限制了凭疮。
然后在網(wǎng)上看到了關(guān)于統(tǒng)一異常處理機(jī)制的東西饭耳,用途就是對(duì)于各種校驗(yàn)產(chǎn)生的異常,也需要像其他封裝好的數(shù)據(jù)一樣执解,對(duì)前臺(tái)展示統(tǒng)一的數(shù)據(jù)寞肖。第二類的校驗(yàn)由于涉及到了數(shù)據(jù)庫(kù),所以一般的操作就是自己查一下數(shù)據(jù)庫(kù)衰腌,然后如果發(fā)現(xiàn)異常就手動(dòng)返回一個(gè)正規(guī)數(shù)據(jù)新蟆,并不是真正意義上的異常。這種方式返回異常的時(shí)候可能跟原來(lái)差不太多右蕊,可能不夠優(yōu)雅琼稻?不對(duì)。好像是這么做不調(diào)用異常的話饶囚,涉及到事務(wù)的情況好像是沒(méi)辦法回滾的帕翻。(事務(wù)這塊也有待考證,網(wǎng)上有的說(shuō)只有沒(méi)被捕獲的RuntimeException才能觸發(fā)事務(wù)回滾)補(bǔ)充:實(shí)驗(yàn)測(cè)試萝风,首先開(kāi)啟事務(wù)必須要聲明 @Transactional(方法級(jí)) 注解嘀掸,然后拋出的繼承的繼承RuntimeException就可以觸發(fā)回滾,之前提到的捕獲應(yīng)該指的是try catch的捕獲规惰,前后文的異常捕獲器并不會(huì)導(dǎo)致事務(wù)不會(huì)回滾睬塌。
而對(duì)于第一類的異常,toString出來(lái)的對(duì)象就比較麻煩了。對(duì)于我這種剛寫Spring兩三天的人揩晴,給我那么那么多數(shù)據(jù)我也沒(méi)啥用勋陪,也看不懂。但是里面的錯(cuò)誤原因文狱,也就是之前我在參數(shù)校驗(yàn)時(shí)候自定義的返回?cái)?shù)據(jù)卻是我想要的粥鞋。按照常規(guī)的做法是,在Controller層綁定一個(gè)BindingResult的對(duì)象瞄崇,跟@Valid和其他請(qǐng)求參數(shù)一起傳進(jìn)來(lái)呻粹,然后再在BindingResult里頭挨個(gè)處理,遍歷拿出來(lái)結(jié)果進(jìn)行獲取苏研。這樣才能對(duì)結(jié)果進(jìn)行定制處理等浊,不然只能在控制臺(tái)報(bào)一些神仙錯(cuò)誤。想一下這時(shí)候就會(huì)發(fā)現(xiàn)摹蘑,對(duì)于參數(shù)驗(yàn)證的報(bào)錯(cuò)和對(duì)BindingResult的處理會(huì)再每個(gè)Controller里頭都寫一次吧差不多筹燕。因?yàn)橐祷亟y(tǒng)一的錯(cuò)誤數(shù)據(jù)嘛。異常捕獲機(jī)制就顯得雪中送炭了這時(shí)候衅鹿。
這時(shí)候在網(wǎng)上看到了關(guān)于一些統(tǒng)一異常處理的東西撒踪,里面用到了全局異常捕獲器。就是對(duì)于某些特有的異常大渤,可以做特有的處理制妄。找到控制臺(tái)對(duì)于參數(shù)校驗(yàn)的一些異常,然后在捕獲器里頭進(jìn)行捕獲泵三,特別處理耕捞。嗯邏輯好簡(jiǎn)單,哇烫幕,迷了我?guī)讉€(gè)小時(shí)的東西隔一天一看就變得俺抽。。沒(méi)那么有成就感了较曼。然后就可以拋出的異常進(jìn)行統(tǒng)一的返回?cái)?shù)據(jù)了磷斧。并且在Controller里面,就不需要開(kāi)發(fā)人員再對(duì)參數(shù)的異常進(jìn)行管理了
附上代碼:
全局異常捕獲器
統(tǒng)一返回?cái)?shù)據(jù)類型
自定義異常處理類
最后希望踩我的同學(xué)出來(lái)交流一下捷犹,個(gè)人也是小白一枚~希望指點(diǎn)
有關(guān)的項(xiàng)目源碼在我的個(gè)人項(xiàng)目中均可以找到弛饭,甚至發(fā)現(xiàn)更神奇的東西噢~(在線表單項(xiàng)目,可自定義表單組件)
小的在此請(qǐng)大家閑暇之余賞個(gè)Star嘻嘻嘻
https://github.com/syhdeclan/OnlineFormJava