spring异常处理机制

来源:互联网 发布:淘宝可以卖电子书吗 编辑:程序博客网 时间:2024/06/06 06:50

点击阅读原文


Spring提供了一系列健全的异常处理框架。我们可以采用@ResponseStatus@ExceptionHandlerHandlerExceptionResolver以及 @ControllerAdvice处理异常。@ResponseStatus可以为异常指定状态码,可以应用到用户定义的异常类以及controller中被@ExceptionHandler注解的方法上。在controller中,我们可以通过使用@ExceptionHandler注解异常处理方法,被注解的方法只能在当前controller内使用。Spring还提供了@ControllerAdvice用于全局异常处理,对所有的controller都有效。定义一个全局异常处理类,并且用@ControllerAdvice注解,在类中需要定义异常处理方法并且用@ExceptionHandler注解。Spring提供了很多种方法处理异常,在XML文件或者java文件中可以使用HandlerExceptionResolver定义异常类型与view名称的映射。下面是一些完整的例子。

 

 

@ExceptionHandler

SpringMVC@ExceptionHandler注解用来处理异常,我们使用这个注解来标注controller方法。如此,被注解的方法可以有ExceptionHttpServletRequesHttpServletResponseSessionWebRequest等任何顺序的参数类型,方法返回值可以是ModelAndView, Model,Map, View, String, @ResponseBody甚至void类型。返回void类型时, 我们也可以利用HttpServletResponse重新定向。

 

@ResponseStatus

@ResponseStatus可以用在定义的类或者controller方法上,它包含两个元素,valuereasonValue用于设置response的状态码,例如404,200等,reason用于响应,可以是内容语句。

 

HandlerExceptionResolver

HandlerExceptionResolver是各个执行时异常处理的接口,它有各种各样的实现,例如ExceptionHandlerExceptionResolver HandlerExceptionResolverComposite,SimpleMappingExceptionResolver等。在例子中,我们采用了SimpleMappingExceptionResolver。它将异常与一个view名称映射,因此它可以展现error页面适用于任何error类型。

 

@ControllerAdvice

@ControllerAdvice注解是在classpath扫描时自动检测的,java配置时我们须要使用@EnableWebMvcSpring中使用@ControllerAdvice@ExceptionHandler做全局异常处理,使用@ControllerAdvice注解定义的类,@ExceptionHandler注解定义类中的方法。底下的例子中,我们使用@ControllerAdvice做全局异常处理。

运行底下的demo,需要的软件环境:

1.Java 7

2.Tomcat 8

3.Eclipse

4.Gradle

5.Spring 4

 

Eclipse中的工程结构图:


Jar依赖文件的Gradle配置:build.gradle

 

例子开始啦,注意注意注意!

 

为了能够采用@ResponseStatus处理异常,我们必须使用ResponseStatus注解我们定义的异常,并且声明状态码和reason

KeywordNotFoundException.java

 

无论我们在应用的任何地方抛出这个异常,404状态码和reason定义的message将会被接收到,在controller中,抛出这个异常,如下:

 

 

KeywordNotFoundException异常抛出后会返回404状态码,全局的异常处理机制会抓取到这个状态码并且处理。否则,404状态码会和@ResponseStatus中定义的消息一起抛出。部署成功后,访问http://localhost:8080/concretepage-1/keyword/info?key=key1011我们会得到如下界面:


@ExceptionHandler异常处理:

@ExceptionHandler应用在被@controller@ControllerAdvice注解的controller中的方法上。为了在controller内部处理异常,我们使用这个注解标注方法,如果需要的话也可以同时使用@ExceptionHandle@ResponseStatus。定义异常处理方法时,同时也定义view名称,异常对象名称等。

MyWorldExceptionController.java

 

当抛出异常时,Spring针对每一个异常类型搜索对应的异常处理方法来处理异常。如果我们返回值为void时,必须使用@ResponseStatus注解方法。任何的全局异常处理方法会抓取到这个状态码。异常处理的机制是,当前controller内没有异常处理方法的话,该异常会被全局异常处理机制抓取到。

 

访问http://localhost:8080/concretepage-1/myworld/check?id=1




由于SQLEXCEPTION的类型,处理方法返回值类型为void且返回状态码为409。全局异常并没有定义409状态码,因此@ResponseStatus定义的reason和状态码一起显示。

访问http://localhost:8080/concretepage-1/myworld/check?id=2

文件找不到异常,我们返回了错误页,该错误页在处理方法中定义了。


myerror.jsp

 

访问http://localhost:8080/concretepage-1/myworld/check?id=3



Controller内部没有定义方法捕获IO异常,因此它被全局处理机制抓获。

 

使用@ControllerAdvice做全局异常处理

为了处理全局异常,spring提供了@ControllerAdvice来注解定义的handler类,类中处理方法用@ExceptionHandler注解

GlobalExceptionHandler.java

 

无论什么时候一个异常被抛出,若它没有被controller内部抓获,它将会被全局异常处理机制抓获。@ControllerAdvice使得全局异常处理对于应用内任何一个controller抛出的异常都可以抓获。这样,spring可以处理具体的error为具体的状态码。举个栗子,我们在全局异常handler类中创建了两个异常处理方法,如下:

globalerror.jsp

404.jsp

 

使用SimpleMappingExceptionResolver处理异常

我们有很多方式定义异常和view的映射,例如HandlerExceptionResolverSimpleMappingExceptionResolverHandlerExceptionResolver的实现类,我们在java配置中定义SimpleMappingExceptionResolverbean,实例化异常和映射view。我们也可以用它定义默认error页面和异常对象。

AppConfig.java

 

举个栗子,我们创建了用户异常,并且与SimpleMappingExceptionResolver  bean映射。Demo里面,我们将定义了的error页面与SimpleMappingExceptionResolver 映射。

 

ElectricityNotFoundException.java

 

error.jsp

 

VillageController.java

 

Demo里,我们用SimpleMappingExceptionResolver处理了Controller异常。

 

访问http://localhost:8080/concretepage-1/myvillage/info?vid=111


 

Demo里面的WebAppInitializer实现。

WebAppInitializer.java

 

成功页面如下:

success.jsp

 

Spring异常处理到此结束,真是一个愉快的旅程!

 

PS: 想要下载源码的,请阅读原文下载代码。