在 JavaEE 項(xiàng)目的開發(fā)中甫男,不管是對底層的數(shù)據(jù)庫操作過程且改,還是業(yè)務(wù)層的處理過程,還是控制層的處理過程板驳,都不可避免會遇到各種可預(yù)知的又跛、不可預(yù)知的異常需要處理。每個(gè)過程都單獨(dú)處理異常若治,系統(tǒng)的代碼耦合度高慨蓝,工作量大且不好統(tǒng)一,維護(hù)的工作量也很大端幼。
SpringMvc 對于異常處理這塊提供了支持礼烈,通過 SpringMvc 提供的全局異常處理機(jī)制,能夠?qū)⑺蓄愋偷漠惓L幚韽母鱾€(gè)處理過程解耦出來婆跑,這樣既保證了相關(guān)處理過程的功能較單一此熬,也實(shí)現(xiàn)了異常信息的統(tǒng)一處理和維護(hù)。
SpringMVC全局異常處理的三種方式
使用 Spring MVC 提供的簡單異常處理器 SimpleMappingExceptionResolver滑进;
實(shí)現(xiàn) Spring 的異常處理接口 HandlerExceptionResolver 自定義自己的異常處理器犀忱;
使用 @ExceptionHandler 注解實(shí)現(xiàn)異常處理;
案例實(shí)操
全局異常處理方式一
配置 SimpleMappingExceptionResolver 對象
<bean class="org.springframework.web.servlet.handler.SimpleMappingException Resolver">
<property name="defaultErrorView" value="error"></property>
<property name="exceptionAttribute" value="ex"></property>
<property name="exceptionMappings">
<props>
<prop key="com.xxx.exception.BusinessException">error1</prop>
<prop key="com.xxx.exception.ParamsException">error2</prop>
</props>
</property>
</bean>
使用 SimpleMappingExceptionResolver 進(jìn)行異常處理扶关,具有集成簡單阴汇、有良好的擴(kuò)展性、對已有代碼沒有入侵性等優(yōu)點(diǎn)驮审,但該方法僅能獲取到異常信息鲫寄,若在出現(xiàn)異常時(shí)吉执,對需要獲取除異常以外的數(shù)據(jù)的情況不適用。
全局異常處理方式二
實(shí)現(xiàn) HandlerExceptionResolver 接口
@Component
public class GlobalException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
Map<String,Object> map=new HashMap<String, Object>();
map.put("ex", ex);
ModelAndView mv=null;
if(ex instanceof ParamsException){
return new ModelAndView("error_param", map);
}
if(ex instanceof BusinessException){
return new ModelAndView("error_business", map);
}
return new ModelAndView("error", map);
}
}
使用實(shí)現(xiàn) HandlerExceptionResolver 接口的異常處理器進(jìn)行異常處理地来,具有集成簡單戳玫、有良好的擴(kuò)展性、對已有代碼沒有入侵性等優(yōu)點(diǎn)未斑,同時(shí)咕宿,在異常處理時(shí)能獲取導(dǎo)致出現(xiàn)異常的對象,有利于提供更詳細(xì)的異常處理信息蜡秽。
全局異常處理方式三
頁面處理器繼承 BaseController
public class BaseController {
@ExceptionHandler
public String exc(HttpServletRequest request,HttpServletResponse
response,Exception ex){
request.setAttribute("ex", ex);
if(ex instanceof ParamsException){
return "error_param";
}
if(ex instanceof BusinessException){
return "error_business";
}
return "error";
}
}
使用 @ExceptionHandler 注解實(shí)現(xiàn)異常處理府阀,具有集成簡單、有擴(kuò)展性好(只需要將要異常處理的 Controller 類繼承于 BaseController 即可)芽突、不需要附加 Spring 配置等優(yōu)點(diǎn)试浙,但該方法對已有代碼存在入侵性(需要修改已有代碼,使相關(guān)類繼承于 BaseController)寞蚌,在異常處理時(shí)不能獲取除異常以外的數(shù)據(jù)田巴。
擴(kuò)展~未捕獲異常的處理
對于 Unchecked Exception 而言,由于代碼不強(qiáng)制捕獲挟秤,往往被忽略壹哺,如果運(yùn)行期產(chǎn)生了 Unchecked Exception,而代碼中又沒有進(jìn)行相應(yīng)的捕獲和處理艘刚,則我們可能不得不面對尷尬的 404管宵、500……等服務(wù)器內(nèi)部錯(cuò)誤提示頁面。我們需要一個(gè)全面而有效的異常處理機(jī)制攀甚。目前大多數(shù)服務(wù)器也都支持在 Web.xml 中通過 <error-page>(Websphere/Weblogic) 或者 <error-code>(Tomcat) 節(jié)點(diǎn)配置特定異常情況的顯示頁面箩朴。修改 web.xml 文件,增加以下內(nèi)容:
<!-- 出錯(cuò)頁面定義 -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>