Spring/SpringBoot统一异常处理@RestControllerAdvice(ExceptionHandleAdvice)

在项目中,我们不可能能够预知并catch所有的异常,为了避免非期望异常抛给客户端,Spring为我们提供了统一异常处理的机制@RestControllerAdvice,能够让我们在逻辑抛出异常时,能够将异常友好化或者指定返回的数据结构给前台。
用法示例如下:

@RestControllerAdvice
public class ExceptionHandleAdvice {
    
    
    private  final Logger logger = LoggerFactory.getLogger(ExceptionHandleAdvice.class);

    @ExceptionHandler(Exception.class)
    public String exceptionHandle(Exception e){
    
    
        logger.error("系统异常:", e);
        return "系统异常!";
    }
}

以上的代码放在Spring工程中,就会将Controller中抛出的异常在这里集中处理,打印日志后返回“系统异常!”给用户端。
写个Controller例子体会一下使用之前和之后的区别:

@RestController
@RequestMapping("/time")
public class TimeController {
    
    

    @GetMapping("/now")
    public LocalDateTime now(){
    
    
        return LocalDateTime.now();
    }

    /**
     * 返回当前时间+count后的时间字符串
     * 
     * @param count 未来天数
     * @return 时间字符串
     */
    @GetMapping("/oneDay")
    public LocalDateTime now(@RequestParam Long count){
    
    
        return LocalDateTime.now().plusDays(count);
    }
}

这是个很简单的controller,就是返回当前时间+count后的时间字符串,我们只需要使用get请求将count传给服务端,那么服务端将返回现在时间+count天的时间字符串。
浏览器测试一下:
正常的时间
当然,这个接口漏洞也很明显,当我们传一个不是Long类型的count值过去就会出现异常:
异常请求
很不友好的异常报错信息,没学过编程的人还以为自己电脑出问题了。所以我们要对用户友好一点,加入上文写的ExceptionHandleAdvice 统一异常处理类再次启动试一下:
处理后的异常
very 友好

这个用法只是@RestControllerAdvice的小实例,我们可以在这个统一异常处理类中添加其他逻辑如:

@RestControllerAdvice
public class ExceptionHandleAdvice {
    
    
    private  final Logger logger = LoggerFactory.getLogger(ExceptionHandleAdvice.class);

    @ExceptionHandler(Exception.class)
    public String exceptionHandle(Exception e) {
    
    
        logger.error("系统异常:", e);
        return "系统异常!";
    }
    // 处理自定义异常
    @ExceptionHandler(TermException.class)
    public String exceptionHandle(TermException termException) {
    
    
        logger.error("自定义异常:", termException);
        return termException.getMessage();
    }

    // 处理正常请求,对时间进行格式化
    @ResponseStatus(HttpStatus.ACCEPTED) // 值为202
    public <T> String sendSuccessResponse(T data) {
    
    
        if (data instanceof LocalDateTime) {
    
    

            return "时间为" + ((LocalDateTime) data).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        }
        return data.toString();
    }
}

当你的Controller抛出了你自定义的异常TermException时,它就会被上面的第二个方法捕获,并将message返回给用户端。测试一下:
先在controller中抛出该异常:

   @GetMapping("/oneDay")
   public LocalDateTime now(@RequestParam Long count){
    
    
       if (count < 0L){
    
    
           throw new TermException("count不能小于0!");
       }
       return LocalDateTime.now().plusDays(count);
   }

重启服务后,请求后结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41674401/article/details/121643986