java异常统一处理

Posted 玲珑塔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java异常统一处理相关的知识,希望对你有一定的参考价值。

一般系统抛出的错误不含错误代码,出去部分的404,500,400之外,我们如果想吧错误代码定义的更细致,就需要自己继承RuntimeExeption这个类后,重新定义构造方法定义自己的错误信息。

技术分享图片
public class DescribeException extends RuntimeException{

    private Integer code;

    /**
     * 继承exception,加入错误状态值
     * @param exceptionEnum
     */
    public DescribeException(ExceptionEnum exceptionEnum) {
        super(exceptionEnum.getMsg());
        this.code = exceptionEnum.getCode();
    }

    /**
     * 自定义错误信息
     * @param message
     * @param code
     */
    public DescribeException(String message, Integer code) {
        super(message);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}
View Code

使用一个handler来判定我们try。。。catch。。。的错误是我们已知的错误还是未知的,如果已知,返回错误,未知返回未知错误和记录日志,留着以后查找错误。

技术分享图片
@ControllerAdvice
    public class ExceptionHandle {

      private final static Logger LOGGER = LoggerFactory.getLogger(ExceptionHandle.class);

      /**
       * 判断错误是否是已定义的已知错误,不是则由未知错误代替,同时记录在log中
       * @param e
       * @return
       */
      @ExceptionHandler(value = Exception.class)
      @ResponseBody
      public Result exceptionGet(Exception e){
          if(e instanceof DescribeException){
              DescribeException MyException = (DescribeException) e;
              return ResultUtil.error(MyException.getCode(),MyException.getMessage());
          }

          LOGGER.error("【系统异常】{}",e);
          return ResultUtil.error(ExceptionEnum.UNKNOW_ERROR);
      }
    }
View Code

这样我们就不用返回日志到前端了,让用户感觉很奇怪。

但是这时候调用接口出现异常,我们怎么来判断是前端还是后端造成的问题呢。这时候就要用aop进行拦截

技术分享图片
@Aspect
@Component
public class HttpAspect {

    private final static Logger LOGGER = LoggerFactory.getLogger(HttpAspect.class);

    @Autowired
    private ExceptionHandle exceptionHandle;

    @Pointcut("execution(public * com.zzp.controller.*.*(..))")
    public void log(){

    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //url
        LOGGER.info("url={}",request.getRequestURL());
        //method
        LOGGER.info("method={}",request.getMethod());
        //ip
        LOGGER.info("id={}",request.getRemoteAddr());
        //class_method
        LOGGER.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
        //args[]
        LOGGER.info("args={}",joinPoint.getArgs());
    }

    @Around("log()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Result result = null;
        try {

        } catch (Exception e) {
            return exceptionHandle.exceptionGet(e);
        }
        if(result == null){
            return proceedingJoinPoint.proceed();
        }else {
            return result;
        }
    }

    @AfterReturning(pointcut = "log()",returning = "object")//打印输出结果
    public void doAfterReturing(Object object){
        LOGGER.info("response={}",object.toString());
    }
}
View Code

 

以上是关于java异常统一处理的主要内容,如果未能解决你的问题,请参考以下文章

Java接口调用统一处理异常

Java异常处理机制

Java 服务器项目风格推荐 - 统一异常处理

java 反射代码片段

java接口定义统一的异常处理,aop

不是所有的Spring Boot异常都能被统一异常处理 | Java Debug 笔记