SpringMVC可以使用統一的異常處理類,而不必在Controller類中使用try catch 包含住業務處理代碼,這樣使得業務代碼更簡潔易懂。
但在使用的過程中,也遇到一個問題,就是想得到處理方法及異常執行個體,在網上找了很久沒有找到合适的,後來直接看了源代碼,原來最多隻接受4個參數,且必須指定類型,否則若使用Object的話,就是當異常執行個體傳遞過來了。
這樣通過對異常的特殊處理,我們可以根據請求是ajax請求還是普通的form請求來使傳回内容為jsp頁面還是json内容。
代碼如下:
@ExceptionHandler({IllegalArgumentException.class})
public ModelAndView handleIllegalArgumentException(HttpServletRequest request, HttpServletResponse response,
HandlerMethod handlerMethod, Exception exception) {
logger.error("handleIllegalArgumentException, err: {}", exception.getMessage(), exception);
ResponseBody responseBody = handlerMethod.getMethodAnnotation(ResponseBody.class);
if (null == responseBody) {
return new ModelAndView("error/500");
}
returnJsonContent(response, exception.getMessage());
return null;
}
private void returnJsonContent(HttpServletResponse response, String errMsg) {
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
response.setCharacterEncoding("UTF-8");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
try {
WebResult fail = WebResult.failure(errMsg);
PrintWriter writer = response.getWriter();
writer.write(JacksonUtil.encode(fail));
writer.flush();
writer.close();
} catch (Exception ioe) {
logger.warn("write response failed: {}", ioe.getMessage());
}
}
有幾個地方要注意一下:
- 這裡要傳回ModelAndView,若要傳回json,則直接傳回null即可。
- HandlerMethod即是指controller類中的處理方法
- exception指抛出的異常,可以對異常進行執行個體類型檢查
源代碼直接看
org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#doResolveHandlerMethodException
方法即可。