Spring中的@ExceptionHandler注解統(tǒng)一異常處理詳解
1,基本使用方法
Spring的@ExceptionHandler可以用來(lái)統(tǒng)一處理方法拋出的異常,比如這樣:
@ExceptionHandler() public String handleExeption2(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:默認(rèn)"; return resultStr; }
當(dāng)我們使用這個(gè)@ExceptionHandler注解時(shí),我們需要定義一個(gè)異常的處理方法,比如上面的handleExeption2()方法,給這個(gè)方法加上@ExceptionHandler注解,這個(gè)方法就會(huì)處理類中其他方法(被@RequestMapping注解)拋出的異常。
2,注解的參數(shù)
@ExceptionHandler注解中可以添加參數(shù),參數(shù)是某個(gè)異常類的class,代表這個(gè)方法專門處理該類異常,比如這樣:
@ExceptionHandler(NumberFormatException.class) public String handleExeption(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:NumberFormatException"; return resultStr; }
此時(shí)注解的參數(shù)是NumberFormatException.class,表示只有方法拋出NumberFormatException時(shí),才會(huì)調(diào)用該方法。
3,就近原則
當(dāng)異常發(fā)生時(shí),Spring會(huì)選擇最接近拋出異常的處理方法。
比如之前提到的NumberFormatException,這個(gè)異常有父類RuntimeException,RuntimeException還有父類Exception,如果我們分別定義異常處理方法,@ExceptionHandler分別使用這三個(gè)異常作為參數(shù),比如這樣:
@ExceptionHandler(NumberFormatException.class) public String handleExeption(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:NumberFormatException"; return resultStr; } @ExceptionHandler() public String handleExeption2(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:默認(rèn)"; return resultStr; } @ExceptionHandler(RuntimeException.class) public String handleExeption3(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:RuntimeException"; return resultStr; }
那么,當(dāng)代碼拋出NumberFormatException時(shí),調(diào)用的方法將是注解參數(shù)NumberFormatException.class的方法,也就是handleExeption(),而當(dāng)代碼拋出IndexOutOfBoundsException時(shí),調(diào)用的方法將是注解參數(shù)RuntimeException的方法,也就是handleExeption3()。
4,注解方法的返回值
標(biāo)識(shí)了@ExceptionHandler注解的方法,返回值類型和標(biāo)識(shí)了@RequestMapping的方法是統(tǒng)一的,可參見(jiàn)@RequestMapping的說(shuō)明,比如默認(rèn)返回Spring的ModelAndView對(duì)象,也可以返回String,這時(shí)的String是ModelAndView的路徑,而不是字符串本身。
有些情況下我們會(huì)給標(biāo)識(shí)了@RequestMapping的方法添加@ResponseBody,比如使用Ajax的場(chǎng)景,直接返回字符串,異常處理類也可以如此操作,添加@ResponseBody注解后,可以直接返回字符串,比如這樣:
@ExceptionHandler(NumberFormatException.class) @ResponseBody public String handleExeption(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:NumberFormatException"; return resultStr; }
這樣的操作可以在執(zhí)行完方法后直接返回字符串本身。
5,錯(cuò)誤的操作
使用@ExceptionHandler時(shí)盡量不要使用相同的注解參數(shù)。
如果我們定義兩個(gè)處理相同異常的處理方法:
@ExceptionHandler(NumberFormatException.class) @ResponseBody public String handleExeption(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:NumberFormatException"; return resultStr; } @ExceptionHandler(NumberFormatException.class) @ResponseBody public String handleExeption2(Exception ex) { System.out.println("拋異常了:" + ex); ex.printStackTrace(); String resultStr = "異常:默認(rèn)"; return resultStr; }
兩個(gè)方法都處理NumberFormatException,這種定義方式編譯可以通過(guò),而當(dāng)NumberFormatException真正被拋出時(shí),Spring會(huì)給我們報(bào)錯(cuò):
java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class java.lang.NumberFormatException]: {public java.lang.String TestController.handleExeption(java.lang.Exception), public java.lang.String TestController.handleExeption2(java.lang.Exception)}
at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.addExceptionMapping(ExceptionHandlerMethodResolver.java:102) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.<init>(ExceptionHandlerMethodResolver.java:66) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.getExceptionHandlerMethod(ExceptionHandlerExceptionResolver.java:458) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:378) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:61) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:140) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:78) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1255) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1062) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) ~[javax.servlet-api-3.1.0.jar:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[javax.servlet-api-3.1.0.jar:3.1.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.29.jar:8.5.29]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.29.jar:8.5.29]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_172]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_172]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.29.jar:8.5.29]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_172]
我在工作當(dāng)中的使用:
做統(tǒng)一異常處理,如下
1.在app-auth服務(wù)我拋出了一個(gè)一異常
2.該異常是在common下面定義的一個(gè)基礎(chǔ)異常
3.然后在common的另一個(gè)模塊中用這個(gè)方法來(lái)統(tǒng)一處理BaseException異常
AjaxResult 是一個(gè)通用的返回前端的對(duì)象,所以只要在需要的地方拋出這個(gè)基礎(chǔ)異常,就可以直接統(tǒng)一處理,返回需要的數(shù)據(jù)到前端。
到此這篇關(guān)于Spring中的@ExceptionHandler注解統(tǒng)一異常處理詳解的文章就介紹到這了,更多相關(guān)@ExceptionHandler注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringMVC使用@ExceptionHandler注解在Controller中處理異常
- Spring的異常處理@ExceptionHandler注解解析
- 關(guān)于SpringBoot使用@ExceptionHandler注解局部異常處理
- Spring中@ExceptionHandler注解的使用方式
- Spring中@ExceptionHandler注解的工作原理詳解
- Spring @ExceptionHandler注解統(tǒng)一異常處理和獲取方法名
- Spring中的@ControllerAdvice和@ExceptionHandler注解處理全局異常
- Spring中的@ExceptionHandler注解詳解與應(yīng)用示例
相關(guān)文章
基于Java中的StringTokenizer類詳解(推薦)
下面小編就為大家?guī)?lái)一篇基于Java中的StringTokenizer類詳解(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05Java GUI編程之貪吃蛇游戲簡(jiǎn)單實(shí)現(xiàn)方法【附demo源碼下載】
這篇文章主要介紹了Java GUI編程之貪吃蛇游戲簡(jiǎn)單實(shí)現(xiàn)方法,詳細(xì)分析了貪吃蛇游戲的具體實(shí)現(xiàn)步驟與相關(guān)注意事項(xiàng),并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2017-09-09SpringBoot整合Retry實(shí)現(xiàn)錯(cuò)誤重試過(guò)程逐步介紹
重試的使用場(chǎng)景比較多,比如調(diào)用遠(yuǎn)程服務(wù)時(shí),由于網(wǎng)絡(luò)或者服務(wù)端響應(yīng)慢導(dǎo)致調(diào)用超時(shí),此時(shí)可以多重試幾次。用定時(shí)任務(wù)也可以實(shí)現(xiàn)重試的效果,但比較麻煩,用Spring Retry的話一個(gè)注解搞定所有,感興趣的可以了解一下2023-02-02mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析
這篇文章主要介紹了mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Spring中的@ControllerAdvice和@ExceptionHandler注解處理全局異常
這篇文章主要介紹了Spring中的@ControllerAdvice和@ExceptionHandler注解處理全局異常,@ControllerAdvice ,@ControllerAdvice是一個(gè)非常有用的注解,顧名思義,這是一個(gè)增強(qiáng)的 Controller,一般配合@ExceptionHandler使用來(lái)處理全局異常,需要的朋友可以參考下2024-01-01