今天碰見一個很奇怪的bug,在本地環境下,api拋出異常爲json格式,而發佈到測試環境上拋出異常爲html視圖。html
項目背景:該工程採用實現BaseController實現HandlerExceptionResolver進行全局的異常處理,有一點特殊的是,該工程須要對內(.net)提供api接口,對外返回視圖,因此,構建了BaseController與BaseApi,其中對異常處理方法resolveException,分別返回json與視圖。json
緣由分析,首先,找到DispatcherServlet類中的processHandlerException方法,該方法用於處理異常,能夠看到這裏handlerExceptionResolvers保存全部的handlerExceptionResolver,從其中獲取ModelAndView(我這裏就是json/視圖)api
下一步app
下一步,這裏ServletInvocableHandlerMethod 爲處理異常的方法測試
進入,異常拋出類與異常處理方法從 new ExceptionHandlerMethodResolver(handlerType)獲得spa
進入ExceptionHandlerMethodResolver.net
addExceptionMapping添加映射關係,進入detectExceptionMappingshtm
detectAnnotationExceptionMappings:發現註解異常。接口
AnnotationUtils.findAnnotation 會發現該方法所在類中的含有@ExceptionHandler的方法。io
這裏因爲咱們沒有使用@ExceptionHandler,因此爲空。
回到最前面,會依次調用實現了handlerExceptionResolver的類,而咱們的BaseApi與BaseController,處理的異常是同樣的,只是返回不一樣,因此,進入任何一個類均可以處理,這裏就有不肯定性,不可以肯定必定會進入該方法所在類所實現的base類所處理的異常的方法,因此會出現這個bug。
從上訴咱們能夠看到,首先會去查找該類是否有@ExceptionHandler的方法,那麼,咱們將實現handlerExceptionResolver,改成使用@ExceptionHandler,解決該問題。