一. 走进自定义统一异常
1.1 什么是自定义统一异常
- 我们在写代码的时候,对异常处理一般是try catch或者抛出异常throws Exception。
- try catch大家都知道,代码中大量的try catch会占用内存影响性能,而且需要在每个方法的代码块加上try catch,非常的繁琐;throws Exception也一样需要加在每个方法后面;
- 自定义异常就是,当我们认为可能为出现错误的地方,不进行try…catch,而是向上层抛出,由最顶层的异常处理类进行统一处理。在这里,我们可以对异常进行针对性的处理,比如加日志,不同异常返回不同结果等。
- Java虽然提供了丰富的异常处理类,但是在项目中还会经常使用自定义异常,其主要原因是Java提供的异常类在某些情况下还是不能满足实际需球。例如以下情况:
- 系统中有些错误是符合Java语法,但不符合业务逻辑。
- 在分层的软件结构中,通常是在表现层统一对系统其他层次的异常进行捕获处理。
总结来说,自定义统一异常,就是我们自己定义一个异常类,在可能出现异常的地方进行手动抛出,由统一异常类进行统一处理。
1.2 优缺点
优点:
- 代码简洁美观,提升开发效率,易于理解
- 易于维护和发现问题,易于统一处理
缺点:
1.3 适用面
- 统一异常基本在所有的项目中均可使用。尤其适用于逻辑较为复杂,业务较为繁琐,问题难以排查,代码量比较多,项目比较大的地方。
- 建议是每个项目都可以做异常处理类,规范化的处理好过杂乱无序。
二. 使用自定义统一异常
2.1 实战代码
首先,定义一个异常类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.xxx.xxx.exception;
import com.xxx.xxx.base.util.common.ResultBean; import lombok.Data;
@Data public class BusinessException extends RuntimeException { public BusinessException() { }
public BusinessException(String message) { super(message); }
public BusinessException(String message, Throwable cause) { super(message, cause); }
public BusinessException(Throwable cause) { super(cause); }
public BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
|
定义一个异常处理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package com.xxx.xxx.exception;
import com.jtd.adp5.base.util.SessionUtil; import com.jtd.adp5.base.util.common.ResultBean; import com.jtd.adp5.dao.po.SysAdmin; import org.apache.log4j.Logger; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession;
@ControllerAdvice public class ControllerAdviceHandler { private static final Logger logger = Logger.getLogger(ControllerAdviceHandler.class);
@ExceptionHandler(value = Exception.class) @ResponseBody public ResultBean exceptionHandler(Exception ex) { if (ex instanceof BusinessException) { logger.error("异常类型为:BusinessException,提示信息为:" + ex.getMessage() + ";下面为详细日志", ex); return ResultBean.createResultByError((ex.getMessage())); } else { logger.error("异常类型为:Exception,提示信息为:" + ex.getMessage() + ";下面为详细日志", ex); return ResultBean.createResultByError(ex.getMessage()); } } }
|
统一返回Bean对象:
1 2 3 4 5 6 7 8 9
| public class ResultBean {
private String msg; private String code; private Object result; private Integer pageNumber; private Integer pageSize; }
|
Controller层代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @RestController @RequestMapping("api") @Slf4j public class ArticlePublishController {
@RequestMapping(value = "xxx", method = RequestMethod.POST) public ResultBean articleList() throws Exception { return ResultBean.createResultBySuccess("成功!"); } }
|
当返回成功时,即返回 成功信息 。 如果抛出异常,则会根据异常不同进行分别处理。
2.2注意事项
- 统一异常处理需要
@ControllerAdvice
注解。
- 在扩展异常时,我们可以创建多个异常类,对每个异常类进行分别的处理。同时,我们也可以分别给特定的错误码,与实际业务结合起来。