`

异常统一处理

    博客分类:
  • Java
阅读更多

一、背景

在实际的工作中,在服务与服务之间的交互中,异常是一个很重要的点,这里的异常有的是正常的业务异常,而有些确实程序本身抛出的异常,例如:服务A依赖服务B,服务B出现了NullPointerException,作为调用方,一定要做好异常的处理。下面是小弟在工作过程中,总结出来的一个统一处理异常的工具。

二、代码实现

1、定义服务返回结果DemoResult

public class DemoResult<T> implements Serializable {
    private String errorCode;
    private String message;
    private T t;
    private boolean isSuccess = true;

    public void setDemoResult(boolean isSuccess, String errorCode, String message) {
        this.isSuccess = isSuccess;
        this.errorCode = errorCode;
        this.message = message;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public boolean isSuccess() {
        return isSuccess;
    }

    public void setSuccess(boolean success) {
        isSuccess = success;
    }

    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

 2、定义自己的异常DemoException

public class DemoException extends RuntimeException {
    private String errorCode;
    private int code;

    public DemoException(String message) {
        super(message);
    }

    public DemoException(String message, String exceptionCode) {
        super(message);
        this.errorCode = exceptionCode;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public int getCode() {
        return this.code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}

 3、定义日志上下文LogContext

public class LogContext {

    private String bizLog;

    private long userId;

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    public String getBizLog() {
        return bizLog;
    }

    public void setBizLog(String bizLog) {
        this.bizLog = bizLog;
    }

    public static LogContext build(String bizLog) {
        LogContext logContext = new LogContext();
        logContext.setBizLog(bizLog);
        return logContext;
    }
}

 4、定义日志上下文的Holder

public class LogContextHolder {
    private static final ThreadLocal<LogContext> holder = new ThreadLocal<>();

    public static void set(LogContext context) {
        if (context != null) {
            holder.set(context);
        }
    }

    public static LogContext getContext() {
        return holder.get();
    }

    public static void remove() {
        holder.remove();
    }

    public static String bizLog() {
        LogContext context = getContext();
        if (context == null) {
            return "";
        }
        return context.getBizLog();
    }

    public static long userId() {
        LogContext context = getContext();
        if (context == null) {
            return 0L;
        }
        return context.getUserId();
    }
}

 5、定义异常处理的executor

public class DemoExecutor {
    private static final Logger logger = LoggerFactory.getLogger(DemoExecutor.class);

    public static <T extends DemoResult> T execut(Supplier<T> fn, Class<T> c, String bizCall, Object... param) {
        T result = null;
        String uuid = UUID.randomUUID().toString();
        String logBiz = bizCall + "-" + uuid;
        try {
            logger.info("bizCall={},param={}", bizCall, param);
            Stopwatch stopwatch = Stopwatch.createStarted();
            LogContextHolder.set(LogContext.build(uuid));
            result = c.newInstance();
            result = fn.get();
            long costs = stopwatch.elapsed(TimeUnit.MILLISECONDS);
            result.setDemoResult(true, result.getErrorCode(), result.getMessage());
            logger.info("BizCall={},result={}, costs={}ms", bizCall, result, costs);
        } catch (DemoException e) {
            if (e.getErrorCode() == null) {
                result.setDemoResult(false, e.getCode(), e.getMessage());
            }
            if (e.getErrorCode() != null) {
                logger.error("error occurred at [" + logBiz + "] result=[" + result + "]", e);
                result.setDemoResult(false, e.getCode(), e.getMessage());
            } else {
                logger.error("error occurred at [" + logBiz + "] result=[" + result + "]", e);
            }
        } catch (Throwable e) {
            if (result != null) {
                logger.error("error occurred at [" + logBiz + "] result=[" + result + "]", e);
                result.setDemoResult(false, e.getCode(), e.getMessage());
            } else {
                logger.error("error occurred at [" + logBiz + "], error={}", e);
            }
        } finally {
            LogContextHolder.remove();
        }
        return result;
    }
}

 6、说明:

       此处只是一个简单的demo,具体的业务异常的定义,还要根据系统的业务要求。此外,使用的JDK版本最好是1.8以上,如果你的工作环境还没有用到JDK1.8,自己可以对该工具进行修改,满足自己的需求就行。

 

分享到:
评论

相关推荐

    java全局异常统一处理

    在Java中,全局异常统一处理是一种常见的错误处理模式,它允许在一个单独的地方集中处理应用程序中抛出的所有异常。这种处理方式有助于简化代码,提高代码的可读性和可维护性。 要实现全局异常统一处理,Java提供了...

    springboot 多模块 集成mybatis redis 日志 异常统一处理,切面拦截器

    springboot多模块项目,集成了mybatis,连接池,redis,日志,sql日志打印,异常统一处理,统一返回格式,mapper文件自动生成,generator xml ,切面日志和拦截器,sql注入过滤,解压即可部署打包启动,包含数据库...

    后端异常统一处理解决方案

    这篇博客“后端异常统一处理解决方案”主要探讨了如何在Spring Boot、SSM(Spring、Spring MVC、MyBatis)框架中有效地管理和处理异常,提供了一种优化的方法来提升应用程序的健壮性。 首先,Spring Boot以其简洁的...

    异常统一处理实例

    异常统一处理实例,实例详解请访问博主博客:http://blog.csdn.net/u013142781

    spring 异常统一处理类.doc

    spring 异常统一处理类.doc ok

    使用Spring AOP对异常进行统一处理

    我们在捕获到异常并对异常进行处理时可能会遇到如下一些问题: 1.不确定应如何处理这些异常 2.需要记录异常日志时没有记录,或者异常在不同的地方重复记录,使得排错调试不方便 ...无法对某些异常进行统一处理和修改。

    详解SpringCloud Finchley Gateway 统一异常处理

    SpringCloud Finchley Gateway 统一异常处理是指在使用 SpringCloud Finchley 版本的 Gateway 时,如何统一处理系统级异常的方法。默认情况下,SpringCloud Gateway 会返回 HTML 格式的错误页面,而不是我们期望的 ...

    springmvc返回json的全局异常统一处理demo

    springmvc返回json的全局异常统一处理demo,有问题可以留言。

    spingmvc+mybatis+统一异常处理机制

    搭建部分大致跟网上其他资料差不多,唯一不同的加入了统一错误处理,为了方便开发人员开发,所有错误码用一张表存在数据库中,然后由应用将整表缓存,缓存采用的spring自带的cache,开发中所有错误包括系统异常在...

    异常统一处理.zip

    Java项目中的异常问题,统一自己写异常的类进行处理。

    Retrofit2+Rxjava2网络请求异常统一封装处理

    本篇文章将详细讲解如何使用Retrofit2和RxJava2进行网络请求,并进行异常统一封装处理,以便提供更好的用户体验和更高效的调试。 Retrofit2是一个由Square公司开发的类型安全的HTTP客户端,它允许我们通过简单的...

    springmvc 异常统一处理的三种方式详解.docx

    在Spring MVC框架中,异常处理是一项关键任务,它确保了应用程序在遇到错误或异常时能够以优雅的方式响应,提供统一的错误信息,并保持代码的整洁和模块化。本篇文章将详细探讨Spring MVC处理异常的三种主要方法:...

    三. spring mvc 异常统一处理

    NULL 博文链接:https://gaojiewyh.iteye.com/blog/1297746

    SpringBoot逻辑异常统一处理方法

    SpringBoot逻辑异常统一处理方法 在本文中,我们将探讨 SpringBoot 逻辑异常统一处理方法,该方法主要介绍了如何在 SpringBoot 项目中实现逻辑异常的统一处理。通过示例代码,我们将展示如何创建一个异常处理核心子...

    (RSA+DES接口加密交互) (logback日志分级) (异常统一处理) (多数据源主主+redis集群) 2

    (RSA+DES接口加密交互) (logback日志分级) (异常统一处理) (多数据源主主+redis集群) SpringSecurity权限控制 带图形验证码自定义认证器 SpringSecurity过滤器 登陆 + JWT + SpringSecurity权限控制

    (RSA+DES接口加密交互) (logback日志分级) (异常统一处理) (多数据源主主+redis集群).zip

    (RSA+DES接口加密交互) (logback日志分级) (异常统一处理) (多数据源主主+redis集群) SpringSecurity权限控制 带图形验证码自定义认证器 SpringSecurity过滤器 登陆 + JWT + SpringSecurity权限控制

    dubbo捕获自定义异常_dubbo异常捕获_dubbo异常_自定义异常_捕捉异常_

    在分布式服务框架 Dubbo 中,异常处理是必不可少的一部分。Dubbo 提供了强大的异常处理机制,使得服务提供者能够向消费者传递自定义异常,从而帮助消费者更好地理解和处理服务调用中的错误情况。本文将深入探讨如何...

    J2EE项目中统一异常处理源码

    综上所述,"J2EE项目中统一异常处理源码"通过自定义异常分析和统一处理策略,实现了对14类异常的精细化管理,提升了项目的健壮性和用户体验。`ExceptionHandler.java`作为核心处理类,包含了捕获、分析和响应异常的...

    C# WINFORM应用程序未处理异常的统一处理技巧

    异常处理是每个应用程序都会用到的,纵然在程序编写期间我们都会最大限度的考虑可能发生的异常并进行相应的处理,但是往往并不能完全考虑周全,百密一疏,出现未处理异常而导致程序出错,数据丢失,如用户输入错误...

Global site tag (gtag.js) - Google Analytics