最近一直没有时间更新是因为一直在更新自己使用的框架。

之后会慢慢带来对之前使用的spring+mvc+mybatis的优化。

会使用一些新的特性,实现一些新的功能。

我会尽量分离业务,封装好再拿出来。

这次带来的是全局异常捕获。

PS:使用的是spring4.3.7版本

PPPPS:当前使用的全局异常捕获方式已更新,不再使用当前博文描述的方式,详细请参考:http://www.cnblogs.com/linkstar/p/8520027.html

实现的功能

首先描述实现的功能:因为在项目中,我们不可否认的会出现异常,而且这些异常并没有进行捕获。经常出现的bug如空指针异常等等。

在之前的项目中,如果我们没有进行任何配置,那么容器会自动打印错误的信息,如果tomcat的404页面,400页面等等。

如果我们在web.xml中进行如下配置,就会拦截错误,然后跳转到指定的错误页面。

<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>

但是这已经落后了,现在我们通过实现spring的HandlerExceptionResolver接口来捕获所有的异常。

如何实现

1、新建GlobalExceptionResolver如下

/**
* 全局异常捕获
* @author XXX
*
*/
public class GlobalExceptionResolver implements HandlerExceptionResolver{ @Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception exception) {
//--------------------------------------------
return null;
}
}

2、在spring配置文件中配置刚才新建的类

<!--全局异常捕捉 -->
<bean class="com.ssm.exception.GlobalExceptionResolver" />

3、根据自己的需求修改GlobalExceptionResolver的横线部分

在你在开发的时候,请返回null,这样这个类就如同不起作用,之前该怎么样就怎么样。

当开发完成之后,根据错误的信息来返回需要的东西了。

首先我们可以做的是打印错误日志,当然也是必须的。

System.err.println("访问" + request.getRequestURI() + " 发生错误, 错误信息:" + exception.getMessage());

这里我只是用控制台举例,你当然可以用日志框架打印。打印信息主要是包括是访问那个地址出现了什么错误。

之后如果你需要返回错误页面,那么就直接在ModelAndView里面写就行了,这里就不多举例了,ModelAndView写过MVC的Controller应该都熟悉。

ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
return modelAndView;

Follow up

以上其实就已经实现了全局捕获异常的功能,你可以自己抛出一个不捕获的异常测试一下是否成功。

当然还有更多对于这个类的说明。

1、注意不同类型和来源的请求。

因为在实际项目中,可能遇到各种请求类型,如正常的get,post。也可能是来自ajax的请求。

所以如果均返回同一个ModelAndView显然可能有点不合适,对于ajax可能需要特别处理。

还有就是如果有手机端和PC在同一个项目中的情况,那么来源不同,返回的页面也可能不同。虽然可以交给前端去做自适应处理,但是我们还是得做好考虑。

总之,要考虑到各种不同的请求,单一返回可能并不适用所有项目。

2、GlobalExceptionResolver这个类推荐放在exception包下,属于一种自定义异常

这个配置推荐放在和web相关的spring配置下,因为和类似一个controller

3、spring是怎么做到的?handler参数又是什么?

肯定有和我一样的好奇宝宝。用了别人好的东西就想知道怎么实现的,但是又很怕麻烦。(推荐自己仔细读源码,不要听我瞎说

首先spring官方文档536页说明了HandlerExceptionResolve

而官方推荐的是使用@ExceptionHandler注解去捕获固定的异常。

然后我查了源码,spring源码中

/**
* Resolve the exception by iterating over the list of configured exception resolvers.
* The first one to return a ModelAndView instance wins. Otherwise {@code null} is returned.
*/
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
if (resolvers != null) {
for (HandlerExceptionResolver handlerExceptionResolver : resolvers) {
ModelAndView mav = handlerExceptionResolver.resolveException(request, response, handler, ex);
if (mav != null) {
return mav;
}
}
}
return null;
}

这是spring默认实现,也就是说,我们没有重写的话,spring是这样执行的,从命名来瞎说就是

如果出现异常,private List<HandlerExceptionResolver> resolvers;

处理异常解析器就会非空

通过循环异常解析器处理resolvers中的异常,然后处理。

最后返回null也就是我们之前所说的不做任何错误页面的那种处理。

然后处理异常打印异常信息是在抽象类里面完成的。

/**
* Check whether this resolver is supposed to apply (i.e. if the supplied handler
* matches any of the configured {@linkplain #setMappedHandlers handlers} or
* {@linkplain #setMappedHandlerClasses handler classes}), and then delegate
* to the {@link #doResolveException} template method.
*/
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) { if (shouldApplyTo(request, handler)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Resolving exception from handler [" + handler + "]: " + ex);
}
prepareResponse(ex, response);
ModelAndView result = doResolveException(request, response, handler, ex);
if (result != null) {
logException(ex, request);
}
return result;
}
else {
return null;
}
}

就是打印错误信息,这里我们看到handler被打印了。

打印的意思是从哪一个handler解析出什么异常。

最后如果有结果依旧返回。

总之我们可以知道的是,spring的handle在处理时发现异常后,HandlerExceptionResolver的列表会被赋值,然后进行处理。

有兴趣的朋友可以继续往下追。

最后

当然这也只是我在github上面见到的一种异常的处理方式,比我之前的好用。

所以我就拿来用了。如果有需要的就拿走,如果你有更好的也欢迎在下面分享。

使用spring利用HandlerExceptionResolver实现全局异常捕获的更多相关文章

  1. spring boot: GlobalDefaultExceptionHandler方法内的友好错误提示,全局异常捕获

    spring boot: GlobalDefaultExceptionHandler方法内的友好错误提示,全局异常捕获 当你的某个控制器内的某个方法报错,基本上回显示出java错误代码,非常不友好,这 ...

  2. Spring-MVC开发之全局异常捕获全面解读

    异常,异常 我们一定要捕获一切该死的异常,宁可错杀一千也不能放过一个! 产品上线后的异常更要命,一定要屏蔽错误内容,以免暴露敏感信息! 在用Spring MVC开发WEB应用时捕获全局异常的方法基本有 ...

  3. SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...

  4. springboot(二 如何访问静态资源和使用模板引擎,以及 全局异常捕获)

    在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /static / ...

  5. Android全局异常捕获

    PS:本文摘抄自<Android高级进阶>,仅供学习使用 Java API提供了一个全局异常捕获处理器,Android引用在Java层捕获Crash依赖的就是Thread.Uncaught ...

  6. MVC 好记星不如烂笔头之 ---> 全局异常捕获以及ACTION捕获

    public class BaseController : Controller { /// <summary> /// Called after the action method is ...

  7. atitit.js浏览器环境下的全局异常捕获

    atitit.js浏览器环境下的全局异常捕获 window.onerror = function(errorMessage, scriptURI, lineNumber) { var s= JSON. ...

  8. C#中的那些全局异常捕获

    1.WPF全局捕获异常     public partial class App : Application     {         public App()         {    // 在异 ...

  9. Asp.Net MVC3(三)-MvcApp实现全局异常捕获

    定义异常捕获类: [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMu ...

随机推荐

  1. Protobuf学习 - 入门

    古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 -- 苏轼·<晁错论> 从公司的项目源码中看到了这个东西,觉得挺好用的,写篇博客做下小总结.下面的操作以C++为编程语言,protoc的版 ...

  2. Android 视频直播 SDK

    Android 视频直播 SDK接入说明 一.名词解释 分辨率:用于计算机视频处理的图像,以水平和垂直方向上所能显示的像素数来表示分辨率.常见视频分辨率的有1080P即1920x1080,720P即1 ...

  3. 关于hession 随笔

    今天遇到一个问题,纠结了很久也没有解决,情况是这样的, 我这个项目使用的是 hession  通信.我做的业务很简单,只是新加了一个接口 ,这 个接口是广告那一块的,数据库在之前的项目里面都没有使用到 ...

  4. python3.4 安装 scrapy 报错 VS2010

    安装scrapy框架报错是常见问题 还好,本人只碰到其中一个bug,以下是此次安装经验 环境 py3.4 windows7 64位 安装有VS2010 pip包管理(pycharm) 报错信息 安装l ...

  5. Struts2学习笔记④

    刚才看书发现了一个问题,就是ActionSupport和Action接口的区别没搞清楚,弄得我以为我之前的代码写错了.其实ActionSupport已经实现了Action接口了,实际开发中也很少使用A ...

  6. 3732: Network

    3732: Network Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 395  Solved: 179[Submit][Status] Descr ...

  7. PHP环境搭建(20161014)

    听课笔记: 上午: 现在PHP的版本一般是5.5,相对于以前的版本移除了一些函数,所以在以后使用到不同版本的PHP时要特别注意 localhost(本机[默认的网址]) my project(我的项目 ...

  8. R处理大数据集

    R会把所有的对象读存入虚拟内存中.对我们大多数用户来说,这种设计可以提高与R相互的速度,但是当分析大数据集时,这种设计会降低程序运行速度有时还会产生跟内存相关的错误. 内存限制主要取决于R的build ...

  9. [Linux] PHP程序员玩转Linux系列-自动备份与SVN

    我的代码经常在开发修改,为了代码的安全性,比如哪天误删了文件,或者哪天改错东西了,可以恢复回来,我要搞代码备份.备份代码,我先做最简单的,使用linux的定时机制加shell命令打包文件,每天按日期保 ...

  10. 源码分析Android Handler是如何实现线程间通信的

    源码分析Android Handler是如何实现线程间通信的 Handler作为Android消息通信的基础,它的使用是每一个开发者都必须掌握的.开发者从一开始就被告知必须在主线程中进行UI操作.但H ...