java spring框架的异常抛出

实习了这么久,现在才发现自己对异常抛出还是只是浅显略懂,这次趁这个机会复习一下java的异常捕获与抛出机制。

1.java捕获异常

简而言之就是try/catch机制,在try部分的代码发生错误时,将错误通过catch捕获,值得注意的是,catch可以有多个,并在每个代码块执行不同的方法。但是匹配机制为从上到下,且只会匹配一个,如果有上面的exception的子集在下面,那下面那个子集的catch将永远不会被匹配到,其会被上面的父类所全部捕获。具体可以参照这里
另外还有throws (在类上声明的部分)可以在方法可能出现问题时抛出异常,然后由调用者进行处理。
如先使用throws声明一个有可能出现错误的方法
然后调用时用try包含此方法
catch抛出同类的异常
注意:此处throws 的异常继承自Exception.class的话,在整个程序某地方必须进行try/catch捕获或者是再次抛出,因为Exception.class属于checked 异常,总要被一个地方所处理。而继承自runtimeException发生也不会导致整个程序停止,所以spring项目中抛出继承自runtimeException的也不用强制throws掉来保证程序的运行,程序会一步步向上抛到jvm给你默认处理(打印错误信息,停止当前线程)
如以下示例:
比如如果service层的一个方法声明了 throws Exception(checked异常),之后在controller层进行调用的话,就会显示Unhandled exception:。
编译器严格地执行 throws 说明符。 如果调用了一个抛出已检查异常的方法, 就必须对它进行处理, 或者将它继续进行传递

将要被调用的方法发现自己很有可能出现异常(当然也可以自己处理),其将异常向上抛出,当调用者进行调用方法时就会出现Unhandled exception:错误,只能在这里进行处理(try/catch)或者是继续抛出(try/catch的catch代码块中再次throw这个异常,如果其异常是exception或者是继承自exception异常的话,则需要再次声明throws xxxexception)

2.java抛出异常(自带异常)

(此处指抛出java自带的异常,实际上自定义异常也得抛)

void process2(String s) {
    if (s==null) {
        throw new NullPointerException();
    }
}
public class Main {
    public static void main(String[] args) {
        try {
            Integer.parseInt("abc");
        } catch (Exception e) {
            System.out.println("catched");
            throw new RuntimeException(e);
        } finally {
            System.out.println("finally");
        }
    }
}

此方法可抛出其空指针异常

3.自定义异常(抛出)

自定义异常,说白了就是继承自官方异常根据具体业务增加部分业务异常,其有两个核心部分,一是自定义异常exception(继承自runtimeException/IOexception等异常),二是exceptionHandler(不过并不建议使用exceptionHandler直接命名,会和注解冲突。此handler类会在exception执行完毕后被指定执行)
在这里插入图片描述
如果需要自定义异常(比如业务中遇到的一些java中没有定义的异常),我们可以继承自java的异常类,进行实现自己业务类型的异常。

Exception

public class JsonException extends BaseException {

    public JsonException(Status status) {
        super(status);
    }

    public JsonException(Integer code, String message) {
        super(code, message);
    }
}
public class PageException extends BaseException {

    public PageException(Status status) {
        super(status);
    }

    public PageException(Integer code, String message) {
        super(code, message);
    }
}
@Data
@EqualsAndHashCode(callSuper = true)
public class BaseException extends RuntimeException {
    private Integer code;
    private String message;

    public BaseException(Status status) {
        super(status.getMessage());
        this.code = status.getCode();
        this.message = status.getMessage();
    }

    public BaseException(Integer code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }
}

在大型业务开发时,建议先定义一个baseException写下基础的方法,然后根据业务进行继承派生。
此处jsonException是前后端交互式用json传输报错数据,pageException指前后端不分离使用模板的情况下传输报错数据。

exceptionHandler

@ControllerAdvice
@Slf4j
public class DemoExceptionHandler {
    private static final String DEFAULT_ERROR_VIEW = "error";

    /**
     * 统一 json 异常处理
     *
     * @param exception JsonException
     * @return 统一返回 json 格式
     */
    @ExceptionHandler(value = JsonException.class)
    @ResponseBody
    public ApiResponse jsonErrorHandler(JsonException exception) {
        log.error("【JsonException】:{}", exception.getMessage());
        return ApiResponse.ofException(exception);
    }

    /**
     * 统一 页面 异常处理
     *
     * @param exception PageException
     * @return 统一跳转到异常页面
     */
    @ExceptionHandler(value = PageException.class)
    public ModelAndView pageErrorHandler(PageException exception) {
        log.error("【DemoPageException】:{}", exception.getMessage());
        ModelAndView view = new ModelAndView();
        view.addObject("message", exception.getMessage());
        view.setViewName(DEFAULT_ERROR_VIEW);
        return view;
    }
}

handler类在开发的过程中需要注意的是:一,在类上注明@ControllerAdvice表明这个是增强类(advice(AOP相关)),二,在方法上注明@ExceptionHandler(value = ***.class)此处制定了其哪个exception类执行完毕后会由这个方法进行处理。
比如以上代码虽然实际走的是json/page的父类baseException的代码,继承后相当于json/pageException包括了其代码,所以其还是会被handler所引到对应的handler方法中。所以,其从baseException继承出的子目的则是将对应的exception引导向对应的handler进行处理

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值