Java 异常

点击蓝字

fe9093df9f4ab2e344da87686d556c1b.png

关注我们

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

90786133827aa012d82aa633a0ed698c.png

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

226b8655082c8b36224a07457b57fce8.png

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

f348d4fc6a8eb52ba054e4adfb2f3f36.png

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

3controller层异常统一处理

(1)创建GlobalExceptionHandler类

  • @ExceptionHandler:用于指定某一类异常处理的方法。

  • @RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成

@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类

@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类

@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(200);
        result.setMessage("成功");
        return result;
    }

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

(4)Controller中的方法

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

4日志打印

try{
            int a=1/0;
}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();// 输出错误类型,详细信息以及行数,但是只能输出在控制台当中,日志文件看不到

java.lang.ArithmeticException: / by zero
    at com.atguigu.yygh.hosp.controller.HospitalSetController.getHospSet(HospitalSetController.java:107)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

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

getMessage查看报错信息:/ by zero

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

e.getStackTrace().toString():[Ljava.lang.StackTraceElement;@504ceeb7

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

java.lang.ArithmeticException: / by zero
    at com.atguigu.yygh.hosp.controller.HospitalSetController.getHospSet(HospitalSetController.java:109)

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

toString查看报错信息:java.lang.ArithmeticException: / by zero

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小技巧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值