使用springboot開發一個RESTful API服務,配置了@ControllerAdvice,其它類型異常都能正常捕獲,就是不能捕獲NoHandlerFoundException,
安裝以往使用springmvc的經驗,需要設置DispatcherServlet.throwExceptionIfNoHandlerFound,NoHandlerFoundException就會被DispatcherSevlet拋出,並被@ControllerAdvice捕獲處理。想來springboot中自然也是可以的。
網上一搜發現,只需設置spring.mvc.throw-exception-if-no-handler-found=true即可。設置后依然無效!
再次搜索,還需要設置spring.resources.add-mappings=false,問題解決!
很奇怪,為什么禁用了資源映射后,問題就解決了呢?
研究DispatcherServlet源碼發現,NoHandlerFoundException異常能否被拋出,關鍵在如下代碼:
1 mappedHandler = getHandler(processedRequest); 2 if (mappedHandler == null || mappedHandler.getHandler() == null) { 3 noHandlerFound(processedRequest, response); 4 return; 5 }
只有第一句代碼找不到對應該請求的處理器時,才會進入下面的noHandler方法去拋出NoHandlerFoundException異常。
通過測試發現,springboot的WebMvcAutoConfiguration會默認配置如下資源映射:
/映射到/static(或/public、/resources、/META-INF/resources) /webjars/ 映射到classpath:/META-INF/resources/webjars/ /**/favicon.ico映射favicon.ico文件.
這下就明白了,即使你的地址錯誤,仍然會匹配到/**這個靜態資源映射地址,就不會進入noHandlerFound方法,自然不會拋出NoHandlerFoundException了。
所以,我們需要的就是改掉默認的靜態資源映射訪問路徑就可以了。
配置如下屬性,NoHandlerFoundException異常就能被@ControllerAdvice捕獲了
1 spring.mvc.throw-exception-if-no-handler-found=true 2 spring.mvc.static-path-pattern=/statics/**