dubbo自定义异常的完整步骤与测试

下面我会详细讲解“dubbo自定义异常的完整步骤与测试”的完整攻略:

规划异常类包结构

首先应该规划好异常类的包结构。通常情况下,我们会把异常类放在com.xxx.exception包中,这个包可以在provider、consumer、api中共用。在com.xxx.exception包中,我们可以建立一些子包,如com.xxx.exception.common表示一些通用的异常,如参数异常、权限异常等;com.xxx.exception.biz表示将业务相关的异常分门别类管理。如:

  • com.xxx.exception.biz.order: 订单相关的异常
  • com.xxx.exception.biz.user: 用户、操作员等相关的异常
  • com.xxx.exception.biz.product: 商品相关的异常
  • com.xxx.exception.biz.account: 账户相关的异常
  • com.xxx.exception.biz.stock: 库存相关的异常
  • com.xxx.exception.biz.finance: 财务相关的异常

当然,包的数量、命名根据实际情况而定。可以参考阿里巴巴的开发规范。

编写异常类

规划好包结构以后,我们就可以开始编写自定义的异常类了。首先我们要确定一下需要自定义的异常类型。

通常情况下,我们自定义的异常应该继承自运行时异常RuntimeException,因为它是编写业务逻辑时,最常用的异常类型。如果一个异常不需要在调用方法中被处理,那么就可以将它定义为运行时异常!

比如我们定义一个用户不存在异常类UserNotFoundException

package com.xxx.exception.biz.user;

public class UserNotFoundException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public UserNotFoundException() {
        super("user not found");
    }
}

如上所示,当我们在调用过程中如果发现需要抛出用户不存在异常时,就可以抛出UserNotFoundException了。如果需要指定异常信息,我们可以通过传参的方式进行。

如果我们的异常类型复杂些,需要包含更多信息,那么就可以自定义一个异常信息对象,如:

package com.xxx.exception.biz.order;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class OrderExceptionInfo {

    private String errorCode;

    private String errorMessage;

    public OrderExceptionInfo(String errorCode, String errorMessage) {
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }
}

然后我们就可以在异常类中引用这个异常信息对象了,如:

package com.xxx.exception.biz.order;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class OrderCreateException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private OrderExceptionInfo exceptionInfo;

    public OrderCreateException(OrderExceptionInfo exceptionInfo) {
        this.exceptionInfo = exceptionInfo;
    }
}

使用自定义异常

在dubbo服务接口中,通常情况下我们不会定义具体的异常信息,而是直接抛出自定义的异常类(已经定义好了的异常类型)

比如:

package com.xxx.api.order;

public interface OrderService {

    // 创建订单
    Long createOrder(OrderDTO orderDTO) throws OrderCreateException;

    // 取消订单
    void cancelOrder(Long orderId) throws OrderCancelException;

    // 查询订单
    OrderDTO getOrder(Long orderId) throws OrderNotFoundException;
}

其中,涉及到3个自定义的异常类型:

  • OrderCreateException: 订单创建异常,可能是参数错误、重复提交等原因
  • OrderCancelException: 订单取消异常,可能是非法操作等原因
  • OrderNotFoundException: 订单不存在异常,查询不到指定订单

接口实现类中,我们可以按照业务规则进行异常的抛出。

异常兜底

如果我们在抛出异常时,考虑到rpc调用过程中,网络传输等原因,抛出的异常类型可能不是我们预期的类型,这个时候就需要在服务消费方(Consumer)进行异常的处理。

比如:

@Reference(version = "1.0.0")
OrderService orderService;

public Long createOrder(OrderDTO orderDTO) {
    try {
        return orderService.createOrder(orderDTO);
    } catch (OrderCreateException e) {
        // 处理自定义异常
        log.error(e.getMessage());
        throw new BizException("订单创建失败", e.getCause());
    } catch (Exception e) {
        // 异常兜底
        log.error("订单创建失败, 参数: {}", orderDTO, e);
        throw new BizException("订单创建失败", e.getCause());
    }
}

如上所示,在捕获自定义异常以外的错误情况中,我们可以通过日志打印出来,记录下请求参数,方便后续排查问题。

测试自定义异常

最后,我们需要对自定义异常进行测试。

@Reference(version = "1.0.0")
OrderService orderService;

@Test(expected = OrderNotFoundException.class)
public void testGetOrder() {
    OrderDTO order = orderService.getOrder(1L);
}

如上所示,在测试中我们使用了@Test(expected)注解来捕获异常,如果我们抛出的异常类型和expected属性指定的异常类型一致,就算测试通过。

除了这种方法,还可以使用junit5中的assertThrows方法来进行测试,比较麻烦些。

@Test
public void testGetOrder() {
    Exception exception = assertThrows(OrderNotFoundException.class, () -> {
        OrderDTO order = orderService.getOrder(1L);
    });

    String expectedMessage = "order not found";
    String actualMessage = exception.getMessage();
    assertTrue(actualMessage.contains(expectedMessage));
}

整个自定义异常的开发到测试流程就介绍完了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:dubbo自定义异常的完整步骤与测试 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • java获取用户输入的字符串方法

    下面我将为你详细讲解“java获取用户输入的字符串方法”的完整攻略。 一、使用Scanner类获取用户输入的字符串 在Java中,可以使用Scanner类来获取用户的输入。Scanner类提供了nextInt()、nextFloat()、nextBoolean()等方法,可以分别获取用户输入的整数、浮点数和布尔值。如果需要获取用户输入的字符串,可以使用Sca…

    Java 2023年5月26日
    00
  • Java之字节码以及优势案例讲解

    Java之字节码以及优势案例讲解 什么是Java字节码? Java字节码是Java源代码编译后得到的二进制字节码文件,其扩展名为.class,使用JVM(Java虚拟机)来运行。相比于源代码,Java字节码更加节省空间,并且可以跨平台运行。 Java字节码可以通过反编译工具获取到其源代码,但是由于编译后的代码进行了优化,所以反编译后的源代码可能不太容易阅读。…

    Java 2023年5月27日
    00
  • 简单学习Java抽象类要点及实例

    下面是关于“简单学习Java抽象类要点及实例”的完整攻略。 什么是抽象类 抽象类是一种特殊的类,它不能实例化,只能被继承。抽象类中可以有抽象方法(没有方法体),也可以有非抽象方法(有方法体),但是抽象类中至少要有一个抽象方法。抽象类的主要作用是为了让子类继承并实现它的抽象方法,以此来完成对某个行为的规范和约束。 抽象类的语法 抽象类的语法格式如下: publ…

    Java 2023年5月31日
    00
  • Java掩码的几种使用例举

    Java掩码的几种使用例举 在Java中,掩码的主要作用是用来过滤或者匹配不同的字节位。掩码是用位运算符来创建的。在Java中,我们可以使用按位与、或、异或等位运算符来创建掩码。 按位与掩码 按位与掩码是将每个位分别与操作数进行运算,返回新的结果。当操作数均为1的时候,该位的掩码返回1,否则返回0。在Java中,我们可以使用“&”符号来表示按位与掩码…

    Java 2023年5月29日
    00
  • 基于Ant路径匹配规则AntPathMatcher的注意事项

    首先,AntPathMatcher是Spring框架中的一个路径匹配器,它可以使用Ant风格的路径模式进行路径的匹配和解析。 Ant风格的路径模式包括: ?:匹配一个字符 *:匹配0个或多个字符 **:匹配0个或多个目录 接下来,我会详细讲解基于Ant路径匹配规则AntPathMatcher的注意事项。 注意事项 1. 对于默认情况下的AntPathMatc…

    Java 2023年6月15日
    00
  • Java 实现协程的方法

    Java 实现协程的方法有很多种,下面会介绍其中两种方式。 一、基于协程库的实现方式 使用协程库实现协程是一种比较常见的方式,常用的协程库有Quasar、Kotlin协程等。这里以Quasar为例来讲解。 Quasar Quasar是一个基于ASM技术的协程库,Quasar可以在Java和Kotlin上实现协程。Quasar提供了协程的核心API和一些常用场…

    Java 2023年5月18日
    00
  • 详解Java的类加载机制及热部署的原理

    讲解“详解Java的类加载机制及热部署的原理”需要从以下三个方面入手: 类加载的过程、类的加载机制和Java的热部署原理。 一、类加载过程 Java的类加载过程分为以下三个部分: 加载:查找并加载类的二进制数据; 链接:将类的二进制数据合并到JVM中; 初始化:对类进行初始化。 其中加载和链接是“类加载”的前两个阶段,初始化是“类加载”结果的最后一个阶段。 …

    Java 2023年5月26日
    00
  • Java 二维数组创建及使用方式

    Java 二维数组是一个数组,数组的每个元素又是一个数组,因此也被称为数组的数组。在Java中,可以使用两种方式来创建二维数组:静态初始化和动态初始化。 静态初始化 静态初始化是在创建数组时直接给数组赋初值,这种方式代码简单,但只能用于初始化固定长度的数组,不能动态添加和删除元素。 示例: int[][] a = {{1,2,3},{4,5,6},{7,8,…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部