问题:本周在把现有项目整合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
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;
}
}
我的具体的FrontEnHelper.responseOutWithJson(response, result);的实现方式如下,其实就是往输出流返回一个json数据:
/**
* 以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哦!