關於spring下自定義異常處理的功能
問題:本週在把現有專案整合shiro,問題是前端使用的是angularjs,如果對於單個的Controller,失敗後可以直接在程式碼塊中做try-catch來捕獲異常,進而返回給頁面或者是ajax的請求,來說明是不成功的。但是現在遇到一個問題是現有的模組以及功能已經有很多了,想要一個個加上try-catch,比較麻煩,於是思考是否有一個全域性處理異常的操作。進過查詢發現有一個org.springframework.web.servlet.HandlerExceptionResolver這個樣一個定義異常處理的介面。
解決方案
(1)自定義或者使用spring自帶的各種異常處理器
例如spring基於註解的異常解析器AnnotationHandlerMethodExceptionResolver 或者是spring自帶全域性異常處理器SimpleMappingExceptionResolver、自定義實現spring的全域性異常解析器HandlerExceptionResolver來處理。
AnnotationHandlerMethodExceptionResolver目前我所知道的是需要在方法上定義異常的型別,如果異常型別多了,寫起程式碼太麻煩,所以我認為不好用。(那位大俠知道不用定義異常型別就處理所有異常,可以留言告訴我,謝謝!)
spring自帶全域性異常處理器SimpleMappingExceptionResolver也是比較繁瑣的,我在專案中配置了,發現在捕獲shiro的沒有許可權的異常的時候,只能做redirect這樣的重定向之類。但是我又不想做跳轉(或者說是沒有辦法做跳轉,因為註解是@responseBody這樣的),最後只能放棄該方法。
自定義實現spring的全域性異常解析器HandlerExceptionResolver來處理我認為是最方便的,當然,這個是針對當前的業務場景而言,並非絕對的。
(2)自定義實現spring的全域性異常解析器HandlerExceptionResolver
1.需要在spring-mvc.xml中配置如下bean,定義一個全域性異常處理類 2.實現介面 2.1:返回json資料,使用ajax請求的比較適合我的具體的FrontEnHelper.responseOutWithJson(response, result);的實現方式如下,其實就是往輸出流返回一個json資料:public class CustomExceptionResolver implements HandlerExceptionResolver { Logger logger = LoggerFactory.getLogger(CustomExceptionResolver.class); /** * <p>Title: resolveException</p> * <p>Description: </p> * @param request * @param response * @param handler * @param ex 系統 丟擲的異常 * @return */ @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { //handler就是處理器介面卡要執行Handler物件(只有method) //列印異常堆疊 ex.printStackTrace(); //錯誤資訊 String msg= ""; CustomException customException = null; if(ex instanceof CustomException){ customException = (CustomException)ex; }else if(ex instanceof AuthorizationException){ customException = new CustomException("沒有選單的許可權,請聯絡管理員!"); }else{ customException = new CustomException("系統發生異常,請聯絡管理員!"); } msg = customException.getMessage(); ResultMsg result=ResultMsg.build(ResultMsg.FAIL_CODE, msg);; FrontEndHelper.responseOutWithJson(response,result); return null; } }
/**
* 以JSON格式輸出
* @param response
*/
public static void responseOutWithJson(HttpServletResponse response,
Object Object) {
String json=JsonUtils.objectToJson(Object);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.append(json);
logger.info("返回json資料=【"+json+"】");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
2.2:返回一個modelAndView,適合跳轉到一個錯誤頁面,此時需要在web.xml中配置錯誤地址,比如是500錯誤,那就配置500,然後會跳轉到error_500的地址,等等。
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error_500</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error_404</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error_500</location>
</error-page>
最後,配置了地址,別忘了你自己要寫一個請求該500或者是404地址的controller哦!