Java中如何自定义异常进行抛出,并且定义全局异常处理类进行捕获异常(详细讲解)?

1.先理解为什么要抛出异常?

 一句话就是为了终止程序,一般是终止业务层也就是service层。

2.为什么要自定义异常抛出?

因为系统提供的异常种类很多,而且代表的含义很多,所以我们需要自己定义一个通用的异常,然后只要是业务层的异常我都抛出这个,只是给它不同的提示信息进行区别。其实大部分业务层抛出异常只是为了快速终止程序,提示给用户到底发生了什么错误。

3.为什么要进行全局异常捕获处理?

(1)如果不捕获当然也可以,但是很不友好,第一请求的响应结果是一个错误页面的标签,并且在控制台会直接打印出一堆很乱的错误信息的追踪。如图:

(2)所以一般情况下还是要捕获,但是很多人可能好奇,try catch不是能捕获吗?虽然能捕获但是不能终止异常,它后面的代码依然会执行,并且全局的异常也没办法做,一般只有编译器异常才会用try catch 例如文件找不到,因为不try catch程序一直报错,一般这种我们也是在catch里面重新抛出我们自定义的异常,然后再进行全局异常捕获。
(3)全局异常捕获的好处,第一可以指定捕获到的全局异常,然后还可以定义响应码和响应结果进行返回,不会出现刚才响应一个html标签奇怪的东西,第二不会在控制台打印出那个异常的错误信息,也很友好。

4.项目中如何自定义异常和全局捕获(实战)

(1)自定义业务层异常ServiceException放在exception包下面

一般包括错误码code和msg,此处多了一个响应枚举ResponseEnum,是因为有些错误很常见,可以统一提前定义在枚举里面,以后写的时候可以直接new throw ServiceException(ResponseEnum.xxx)更方便一些,当然一般情况下还是直接传入code和msg

package com.fzy.exception;

import com.fzy.constant.ResponseEnum;
import lombok.Data;

@Data
public class ServiceException extends RuntimeException {
    private ResponseEnum responseEnum;
    private Integer code;
    private String msg;

    public ServiceException(ResponseEnum responseEnum) {
        super(responseEnum.getMessage());
        this.responseEnum = responseEnum;
        this.code = responseEnum.getCode();
        this.msg = responseEnum.getMessage();
    }

    public ServiceException(Integer code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public ServiceException(String msg) {
        super(msg);
        this.code = ResponseEnum.FAILURE.getCode();
        this.msg = msg;
    }
}

(2)响应的异常枚举ResponseEnum

package com.fzy.constant;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum ResponseEnum {
    SUCCESS(200,"成功"),
    FAILURE(500,"服务器错误"),
    FILE_SIZE_ERROR(500, "文件大小异常");
    private Integer code;
    private String message;
}

(3)返回给前端的ResponseVO

package com.fzy.result;

import com.fzy.constant.ResponseEnum;
import lombok.Data;

@Data
public class ResponseVO<T> {
    private Integer code;
    private String message;
    private T data;

    public ResponseVO(ResponseEnum resultEnum) {
        this.code = resultEnum.getCode();
        this.message = resultEnum.getMessage();
    }
    public ResponseVO(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    public ResponseVO(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
    public ResponseVO(T data) {
        this.data = data;
    }
}

(4)全局异常处理类SystemGlobalExceptionHandler,放到handler包下面

其中@ExceptionHandler主要是表明捕获哪个异常,可以给参数进行指定,e.getMessage是它父类的方法,并且我们在 new ServiceException时调用的super方法就是给父类中的Message赋值。

package com.fzy.handler;

import com.fzy.exception.ServiceException;
import com.fzy.result.ResponseVO;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class SystemGlobalExceptionHandler {
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseVO exceptionHandler(ServiceException e){
        System.out.println(e.getMessage());
        if (e.getResponseEnum() != null) {
            return new ResponseVO<>(e.getResponseEnum());
        } else {
            return new ResponseVO<>(e.getCode(), e.getMsg());
        }
    }
}

总结:上面这种写法是为了更好的封装和规范开发,多理解一下,一般只在Service层进行抛出异常终止程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值