(转载)Spring异常处理@ExceptionHandler

2019-12-10  本文已影响0人  dbc94a66f502

原文地址:https://www.cnblogs.com/shuimuzhushui/p/6791600.html
最近学习Spring时,认识到Spring异常处理的强大。之前处理工程异常,代码中最常见的就是try-catch-finally,有时一个try,多个catch,覆盖了核心业务逻辑:

try{
    ..........
}catch(Exception1 e){
    ..........
}catch(Exception2 e){
    ...........
}catch(Exception3 e){
    ...........
}

Spring能够较好的处理这种问题,核心如下,文章主要关注前两个:

@ExceptionHandler

源码如下:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
    Class<? extends Throwable>[] value() default {};
}

该注解作用对象为方法,并且在运行时有效,value()可以指定异常类。由该注解注释的方法可以具有灵活的输入参数(详细参见Spring API):

方法返回值可以为:

@ControllerAdvice

源码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<?>[] assignableTypes() default {};

    Class<? extends Annotation>[] annotations() default {};
}

该注解作用对象为TYPE,包括类、接口和枚举等,在运行时有效,并且可以通过Spring扫描为bean组件。其可以包含由@ExceptionHandler、@InitBinder 和@ModelAttribute标注的方法,可以处理多个Controller类,这样所有控制器的异常可以在一个地方进行处理。

实例

异常类:

public class CustomGenericException extends RuntimeException{
    private static final long serialVersionUID = 1L;

    private String errCode;
    private String errMsg;

    public String getErrCode() {
        return errCode;
    }

    public void setErrCode(String errCode) {
        this.errCode = errCode;
    }

    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    public CustomGenericException(String errCode, String errMsg) {
        this.errCode = errCode;
        this.errMsg = errMsg;
    }
}

控制器:

@Controller
@RequestMapping("/exception")
public class ExceptionController {

    @RequestMapping(value = "/{type}", method = RequestMethod.GET)
    public ModelAndView getPages(@PathVariable(value = "type") String type) throws Exception{
        if ("error".equals(type)) {
            // 由handleCustomException处理
            throw new CustomGenericException("E888", "This is custom message");
        } else if ("io-error".equals(type)) {
            // 由handleAllException处理
            throw new IOException();
        } else {
            return new ModelAndView("index").addObject("msg", type);
        }
    }
}

异常处理类:

@ControllerAdvice
public class ExceptionsHandler {

    @ExceptionHandler(CustomGenericException.class)//可以直接写@ExceptionHandler,不指明异常类,会自动映射
    public ModelAndView customGenericExceptionHnadler(CustomGenericException exception){ //还可以声明接收其他任意参数
        ModelAndView modelAndView = new ModelAndView("generic_error");
        modelAndView.addObject("errCode",exception.getErrCode());
        modelAndView.addObject("errMsg",exception.getErrMsg());
        return modelAndView;
    }

    @ExceptionHandler(Exception.class)//可以直接写@EceptionHandler,IOExeption继承于Exception
    public ModelAndView allExceptionHandler(Exception exception){
        ModelAndView modelAndView = new ModelAndView("generic_error");
        modelAndView.addObject("errMsg", "this is Exception.class");
        return modelAndView;
    }
}

JSP页面:

正常页面index.jsp:

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<h2>Spring MVC @ExceptionHandler Example</h2>

<c:if test="${not empty msg}">
    <h2>${msg}</h2>
</c:if>

</body>
</html>

异常处理页面generic_error.jsp

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>

<c:if test="${not empty errCode}">
    <h1>${errCode} : System Errors</h1>
</c:if>

<c:if test="${empty errCode}">
    <h1>System Errors</h1>
</c:if>

<c:if test="${not empty errMsg}">
    <h2>${errMsg}</h2>
</c:if>

</body>
</html>

测试运行如下:

正常情况:

image

CustomGenericException异常情况:

image

IOException异常情况:

image

总结

参考:

上一篇下一篇

猜你喜欢

热点阅读