Java 异常

2022-10-27 10:41:55 浏览数 (3)

1service层异常处理:

(1)常用@Transcational注解处理service层的异常,该注解可以设置在方法上,也可以设置在类上

(2)@Transactional遇到未被捕获的RuntimeException(运行时异常)默认会回滚,若使用try-catch捕获了异常,需要在catch中再抛出异常(throw new RuntimeException()),才能被捕获近而回滚 。controller层要继续捕获这个异常并处理

(3)@Transactional(rollbackFor=Exception.class)之后Exception异常也可回滚

(4)可以在catch块中使用

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常

2service层throw new RuntimeException("程序异常"),controller层使用Exception类的getMessage()方法输出异常信息原理

(1)首先调用RuntimeException构造器,传递message

(2)然后信息赋值到这里

(3)然后这里就有了数值

(4)由于是父类,所以Exception调用的时候getMessage()的时候,就会捕获这个信息

3controller层异常统一处理

(1)创建GlobalExceptionHandler类

  • @ExceptionHandler:用于指定某一类异常处理的方法。
  • @RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成
代码语言:javascript复制
@ControllerAdvice
public class GlobalExceptionHandler {
    //controller层遇到Exception返回
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e){
        //打印在控制台
        e.printStackTrace();
        //返回到前端
        return Result.fail();
    }

    //controller层遇到YyghException返回,需要先自定义YyghException异常
    @ExceptionHandler(YyghException.class)
    @ResponseBody
    public Result error(YyghException e){
        e.printStackTrace();
        return Result.build(e.getCode(), e.getMessage());
    }
}

(2)创建自定义异常类:YyghException类

代码语言:javascript复制
@Data
@ApiModel(value = "自定义全局异常类")
public class YyghException extends RuntimeException {

    @ApiModelProperty(value = "异常状态码")
    private Integer code;

    /**
     * 通过状态码和错误消息创建异常对象
     * @param message
     * @param code
     */
    public YyghException(String message, Integer code) {
        super(message);
        this.code = code;
    }
}

(3)Result类

代码语言:javascript复制
@Data
@ApiModel(value = "全局统一返回结果")
public class Result<T> {

    @ApiModelProperty(value = "返回码")
    private Integer code;

    @ApiModelProperty(value = "返回消息")
    private String message;

    public Result(){}

    public static <T> Result<T> build(Integer code, String message) {
        Result<T> result = new Result<T>();
        result.setCode(code);
        result.setMessage(message);
        return result;
    }

    public static<T> Result<T> ok(){
        Result<T> result = new Result<T>();
        result.setCode();
        result.setMessage("成功");
        return result;
    }

    public static<T> Result<T> fail(){
        Result<T> result = new Result<T>();
        result.setCode();
        result.setMessage("失败");
        return result;
    }
}

(4)Controller中的方法

代码语言:javascript复制
public Result test(){
        //无需捕获,遇到Exception异常,直接调用GlobalExceptionHandler中@ExceptionHandler(Exception.class)注解下的方法
        int a=/;
    return Result.ok();
}
代码语言:javascript复制
public Result test(){
        //调用GlobalExceptionHandler中@ExceptionHandler(Exception.class)注解下的方法
        try {
            int a =  / ;
        }catch(Exception e){
            throw new YyghException("自定义YyghException",);
        }
    return Result.ok();
}

4日志打印

代码语言:javascript复制
try{
            int a=/;
}catch(Exception e){
            e.printStackTrace();
            //这种写法只会输出逗号前面的内容,一般不这么写
            logger.error("getMessage查看报错信息:",e.getMessage());
            logger.error("getMessage查看报错信息:" e.getMessage());
            logger.error("getMessage查看报错信息:{}",e.getMessage());
            logger.error("toString查看报错信息:{}",e.toString());
            logger.error("e查看报错信息:",e);
            logger.error("e.getStackTrace().toString():{}",e.getStackTrace().toString());
            logger.error("第一个Object参数:{},第二个Throwable:{}",hospitalSetService.getById(id),e);
            logger.error("第一个Throwable:{},第二个Object参数:{}",e,hospitalSetService.getById(id));
        }

e.printStackTrace();// 输出错误类型,详细信息以及行数,但是只能输出在控制台当中,日志文件看不到

代码语言:javascript复制
java.lang.ArithmeticException: / by zero
    at com.atguigu.yygh.hosp.controller.HospitalSetController.getHospSet(HospitalSetController.java:)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

logger.error("getMessage查看报错信息:" e.getMessage());和 logger.error("getMessage查看报错信息:{}",e.getMessage());;// 只能输出错误类型后面的简短信息,不便于排错

代码语言:javascript复制
getMessage查看报错信息:/ by zero

logger.error("e.getStackTrace().toString():{}",e.getStackTrace().toString());// 不能输出错误信息,返回一个对象

代码语言:javascript复制
e.getStackTrace().toString():[Ljava.lang.StackTraceElement;@ceeb7

logger.error("e查看报错信息:",e);// 可以在日志中输出完整的错误信息,""里要写内容,和e.printStackTrace()效果一样,只不过可以输出到日志中

代码语言:javascript复制
java.lang.ArithmeticException: / by zero
    at com.atguigu.yygh.hosp.controller.HospitalSetController.getHospSet(HospitalSetController.java:)

logger.error("toString查看报错信息:{}",e.toString());// 只能输出简短的错误信息,不能输出行数,不便于排错

代码语言:javascript复制
toString查看报错信息:java.lang.ArithmeticException: / by zero

logger打印日志的时候:当参数被识别为Object对象的时候,logger中的占位符会生效,如果识别为Throwable则不会生效。

只要将异常信息e作为最后一个参数,不论使用还是不使用占位符,都不会影响异常信息的输出,只是占位符不起作用。异常信息e若不是最后一个参数,则占位符会起作用,但是异常信息可能会显示不全

1 人点赞