springMVC 统一异常处理异常处理类的使用

 在项目开发中各层中都会不可避免的遇到各种可预知和不可预知的异常需要处理,为只专注业务逻辑的实现,需要将异常信息进行统一管理维护处理。

         springmvc就是将异常层层向外抛出,最后由springmvc的前端控制器调用异常处理组件HandlerExceptionResolver(处理器异常解析器)进行处理
————————————————

统一处理某一类异常,能够减少代码的重复度和复杂度,有利于代码的维护。springmvc统一处理异常有三种方式

  • @ExceptionHandler

    使用@ExceptionHandler注解作用在方法上面,参数是具体的异常类型。一旦系统抛出这种类型的异常时,会引导到该方法来处理。但是它的缺陷很明显

处理异常的方法和出错的方法(或者异常最终抛出来的地方)必须在同一个controller,不能全局控制。

@RequestMapping(value = "/error111",method = RequestMethod.GET)
    @ResponseBody
    public ResultBean error111(){
        service.test();
      //  int i = 1/0;

        return null;

    }

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public String error3(){
        return "run time exception";
    }


@org.springframework.stereotype.Service
public class Service {

    public void test(){

        int i = 1/0;
    }
}
  • @ControllerAdvice + @ExceptionHandler

使用@ControllerAdvice 和@ExceptionHandler  可以全局控制异常,使业务逻辑和异常处理分隔开。

@ControllerAdvice
public class GlobalExceptionHandler {


    @ExceptionHandler(MyException.class)
    @ResponseBody
    public ResultBean handleMyException(MyException e){
        System.out.println("handleMyException....");
        return new ResultBean(e.getErrorEnum().getCode(),e.getErrorEnum().getMsg());
    }


}


public class MyException extends RuntimeException {

    private  ErrorEnum errorEnum;

    public MyException(ErrorEnum errorEnum){
        this.errorEnum  = errorEnum;
    }



    public ErrorEnum getErrorEnum() {
        return errorEnum;
    }
}



public enum ErrorEnum {

    SystemError("999","系统异常,请联系管理员"),
    MyError1("001","自定义异常1"),
    MyError2("002","自定义异常2"),
    MyError3("003","自定义异常3");

    private String code;
    private String msg;

    ErrorEnum(String code,String msg){
        this.code = code;
        this.msg = msg;

    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}



@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class ResultBean <T>{

    private final String SUCCESSCODE = "000";
    private final String SUCCESSMSG = "请求成功";

    /**
     *999 : 请求失败 (系统异常:这时候具体问题原因要去看日志)
     *000 : 请求成功
     *
     *001 : 自定义异常1,用户一眼就能看出问题在哪
     *002 : 自定义异常2,用户一眼就能看出问题在哪
     *003 : 自定义异常3,用户一眼就能看出问题在哪
     *
     *
     *
     */
    public String code;

    public String message;

    public T data;


    public ResultBean(){
        this.code = SUCCESSCODE;
        this.message = SUCCESSMSG;

    }

    public ResultBean(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public ResultBean(T data) {
        this();
        this.data = data;
    }
}

实现 HandlerExceptionResolver 接口

@Component  
public class MyException implements HandlerExceptionResolver{  

    /**  
     * TODO 简单描述该方法的实现功能(可选).  
     * @see org.springframework.web.servlet.HandlerExceptionResolver#resolveException(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)  
     */   
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,  
            Exception ex) {  
        System.out.println("This is exception handler method!");  
        return null;  
    }  
}

优先级
既然在SpringMVC中有两种处理异常的方式,那么就存在一个优先级的问题:

当发生异常的时候,SpringMVC会如下处理:

(1)SpringMVC会先从配置文件找异常解析器HandlerExceptionResolver

(2)如果找到了异常异常解析器,那么接下来就会判断该异常解析器能否处理当前发生的异常

(3)如果可以处理的话,那么就进行处理,然后给前台返回对应的异常视图

(4)如果没有找到对应的异常解析器或者是找到的异常解析器不能处理当前的异常的时候,就看当前的Controller中有没有提供对应的异常处理器,如果提供了就由Controller自己进行处理并返回对应的视图

(5)如果配置文件里面没有定义对应的异常解析器,而当前Controller中也没有定义的话,就看有没有全局ControllerAdvice提供的全局异常处理器,如果没有那么该异常就会被抛出来。

发布了686 篇原创文章 · 获赞 632 · 访问量 127万+

猜你喜欢

转载自blog.csdn.net/zhangchen124/article/details/104226387