Spring的@ExceptionHandler注解使用方法

x33g5p2x  于2021-11-25 转载在 Spring  
字(3.4k)|赞(0)|评价(0)|浏览(240)

1,基本使用方法

Spring的@ExceptionHandler可以用来统一处理方法抛出的异常,比如这样:

@ExceptionHandler()
public String handleExeption2(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:默认";
    return resultStr;
}

当我们使用这个@ExceptionHandler注解时,我们需要定义一个异常的处理方法,比如上面的handleExeption2()方法,给这个方法加上@ExceptionHandler注解,这个方法就会处理类中其他方法(被@RequestMapping注解)抛出的异常。

2,注解的参数

@ExceptionHandler注解中可以添加参数,参数是某个异常类的class,代表这个方法专门处理该类异常,比如这样:

@ExceptionHandler(NumberFormatException.class)
public String handleExeption(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:NumberFormatException";
    return resultStr;
}

此时注解的参数是NumberFormatException.class,表示只有方法抛出NumberFormatException时,才会调用该方法。

3,就近原则

当异常发生时,Spring会选择最接近抛出异常的处理方法。

比如之前提到的NumberFormatException,这个异常有父类RuntimeException,RuntimeException还有父类Exception,如果我们分别定义异常处理方法,@ExceptionHandler分别使用这三个异常作为参数,比如这样:

@ExceptionHandler(NumberFormatException.class)
public String handleExeption(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:NumberFormatException";
    return resultStr;
}
 
@ExceptionHandler()
public String handleExeption2(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:默认";
    return resultStr;
}
 
@ExceptionHandler(RuntimeException.class)
public String handleExeption3(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:RuntimeException";
    return resultStr;
}

那么,当代码抛出NumberFormatException时,调用的方法将是注解参数NumberFormatException.class的方法,也就是handleExeption(),而当代码抛出IndexOutOfBoundsException时,调用的方法将是注解参数RuntimeException的方法,也就是handleExeption3()。

4,注解方法的返回值

标识了@ExceptionHandler注解的方法,返回值类型和标识了@RequestMapping的方法是统一的,可参见@RequestMapping的说明,比如默认返回Spring的ModelAndView对象,也可以返回String,这时的String是ModelAndView的路径,而不是字符串本身。

有些情况下我们会给标识了@RequestMapping的方法添加**@ResponseBody**,比如使用Ajax的场景,直接返回字符串,异常处理类也可以如此操作,添加@ResponseBody注解后,可以直接返回字符串,比如这样:

@ExceptionHandler(NumberFormatException.class)
@ResponseBody
public String handleExeption(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:NumberFormatException";
    return resultStr;
}

这样的操作可以在执行完方法后直接返回字符串本身。

5,错误的操作

使用@ExceptionHandler时尽量不要使用相同的注解参数

如果我们定义两个处理相同异常的处理方法:

@ExceptionHandler(NumberFormatException.class)
@ResponseBody
public String handleExeption(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:NumberFormatException";
    return resultStr;
}
 
@ExceptionHandler(NumberFormatException.class)
@ResponseBody
public String handleExeption2(Exception ex) {
    System.out.println("抛异常了:" + ex);
    ex.printStackTrace();
    String resultStr = "异常:默认";
    return resultStr;
}

两个方法都处理NumberFormatException,这种定义方式编译可以通过,而当NumberFormatException真正被抛出时,Spring会给我们报错:

java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class java.lang.NumberFormatException]: {public java.lang.String TestController.handleExeption(java.lang.Exception), public java.lang.String TestController.handleExeption2(java.lang.Exception)}
	at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.addExceptionMapping(ExceptionHandlerMethodResolver.java:102) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
	at org.springframework.web.method.annotation.ExceptionHandlerMethodResolver.<init>(ExceptionHandlerMethodResolver.java:66) ~[spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]

相关文章

微信公众号

最新文章

更多