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
方法即可。