Java異常分類及統(tǒng)一處理詳解
一、異常分類
java異常分為"檢查"和"非檢查"兩類,"檢查"二字的意思是,代碼編譯時,編譯器會去Check一下有沒有進(jìn)行異常處理(捕獲或向上拋),對于歸類為需要檢查的異常,若沒處理,編譯就過不去。
初學(xué)的時候,常常想為啥異常要這樣分類處理? 后來明白了些,異常不過兩種:主觀和客觀,一個大多數(shù)情況下可以避免,一個大多數(shù)情況下無法避免。
像NullPointerException這類異常,大多跟程序員素質(zhì)掛鉤(開發(fā)好,測試好, 基本不會在系統(tǒng)運(yùn)行后蹦出來), 基本是可以避免的,java語法當(dāng)初把它們對類為‘非檢查異常',也算給程序員和編譯器省了不少事;
而像IOException這類跟外在環(huán)境有關(guān)的異常,幾乎是不可避免的(指不定哪一天那一秒網(wǎng)絡(luò)就掛了),但是當(dāng)不期而遇時,程序還是要有所作為,所以編譯器有必要督促一下程序員,Check一下,看看是是否對這些可能不期而至的異常進(jìn)行了處理。當(dāng)Exception對象傳遞到某個節(jié)點后,程序就可以執(zhí)行一些措施了,比如:給用戶返回一個提示("系統(tǒng)繁忙,請重試"),給監(jiān)控平臺推送一個異常消息等等。
二、異常的統(tǒng)一返回處理
1、容器處理
下面列舉Tomcat的處理方式,在web.xml下配置,按http返回碼或Exception類型來處理:
<error-page> <error-code>404</error-code> <location>/WEB-INF/views/error/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/views/error/500.jsp</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/WEB-INF/views/error/throwable.jsp</location> </error-page>
缺點:無法處理不需要返回html的請求,比如ajax;
2、框架處理
下面列舉Spring MVC的處理方式
(1)使用Spring MVC自帶的簡單異常處理器SimpleMappingExceptionResolver;
(2)實現(xiàn)接口HandlerExceptionResolver 自定義異常處理器; (建議使用,可支持ajax等擴(kuò)展)
(3)使用@ExceptionHandler注解實現(xiàn)異常處理;
第(1)種,在spring-mvc.xml下配置
<!-- 將Controller拋出的異常轉(zhuǎn)到特定視圖 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- 不同異常分開跳轉(zhuǎn)-->
<!-- 可以自定義不同的異常-->
<prop key="com.test.MyException1">/error/e1</prop>
<prop key="com.test.MyException2">/error/e2</prop>
<!-- 如果不想自定義異常,只配置下面的即可-->
<prop key="java.lang.Throwable">/error/500</prop>
</props>
</property>
</bean>
缺點:無法處理不需要返回html的請求;
第(2)種,自定義HandlerExceptionResolver接口的實現(xiàn)類
/**
* 自定義異常處理器:支持ajax
* @author wangxu
*
*/
public class MyExceptionHandler implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
/* 區(qū)分ajax */
boolean isAjax = request.getHeader("X-Requested-With") != null
&& "XMLHttpRequest".equals(request
.getHeader("X-Requested-With").toString());
if (!isAjax) {
if (ex instanceof com.test.MyException1) {
return new ModelAndView("/error/e1");
} else if (ex instanceof com.test.MyException1) {
return new ModelAndView("/error/e2");
} else {
return new ModelAndView("/error/500");
}
}
String jsonRes = "{\"message\":\"" + "系統(tǒng)異常" + "\"}";// 自定義結(jié)構(gòu)和前臺對接
PrintWriter out = null;
try {
out = response.getWriter();
request.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");
out.print(jsonRes);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
}
return null;
}
}
并在spring-mvc.xml下注冊處理器
<bean id="exceptionHandler" class="com.test.MyExceptionHandler"/>
優(yōu)點:可以處理ajax請求,也方便編碼實現(xiàn)功能擴(kuò)展,比如異常的監(jiān)控等。
第(3)種,@ExceptionHandler注解
@Controller
public class TestExceptionHandlerController {
@ExceptionHandler({ MyException1.class })
public String exception(MyException1 e) {
return "/error/e1";
}
@RequestMapping("/marry")
public void test() {
throw new MyException1("沒錢!");
}
}
缺點:@ExceptionHandler的方法,必須和可能拋異常的方法在一同個Controller下。(不建議使用)
3、結(jié)合
實際項目中,在處理異常的統(tǒng)一返回時,會將一些自定義的異?;蛘邤U(kuò)展交給框架,將http返回碼的映射交給容器,因為http返回碼更外層,有些到不了框架,有些對于框架來說就不是一個異常(比如404之與Spring MVC)??蚣苁沁\(yùn)行在容器里的,當(dāng)框架優(yōu)先拿到異常并做了返回處理,容器就不會再進(jìn)行映射。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
java線程池對象ThreadPoolExecutor的深入講解
在我們的開發(fā)中“池”的概念并不罕見,有數(shù)據(jù)庫連接池、線程池、對象池、常量池等等。下面這篇文章主要給大家介紹了關(guān)于java線程池對象ThreadPoolExecutor的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧2018-09-09
Java中HashMap和Hashtable的區(qū)別淺析
這篇文章主要介紹了Java中HashMap和Hashtable的區(qū)別淺析,本文總結(jié)了6條它們之間的不同之處,需要的朋友可以參考下2015-03-03
springboot全局字符編碼設(shè)置方式(解決亂碼問題)
這篇文章主要介紹了springboot全局字符編碼設(shè)置方式(解決亂碼問題),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
spring?boot+vue實現(xiàn)JSAPI微信支付的完整步驟
JSAPI支付是用戶在微信中打開商戶的H5頁面,商戶在H5頁面通過調(diào)用微信支付提供的JSAPI接口調(diào)起微信支付模塊完成支付,下面這篇文章主要給大家介紹了關(guān)于spring?boot+vue實現(xiàn)JSAPI微信支付的相關(guān)資料,需要的朋友可以參考下2022-05-05
SpringBoot整合Druid數(shù)據(jù)源的方法實現(xiàn)
Druid是阿里開發(fā)的一款開源的數(shù)據(jù)源,被很多人認(rèn)為是Java語言中最好的數(shù)據(jù)庫連接池,本文主要介紹了SpringBoot整合Druid數(shù)據(jù)源的方法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06

