热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

dubbo自动转换异常类型的坑

大家都知道,大部分企业都会有自己的自定义异常。在某种特殊情况下,dubbo会将自定义异常转换为RuntimeException,例如&#

大家都知道,大部分企业都会有自己的自定义异常。

在某种特殊情况下,dubbo会将自定义异常转换为RuntimeException,例如:

我在dubbo-provider-service-impl里自定义一个异常TestException

public class TestException extends RuntimeException{private static final long serialVersionUID = 2663095676298579664L;private String message;public TestException() {}public TestException(Exception e) {super(e.getMessage(), e instanceof TestException ? (TestException)e : e);this.message = e.getMessage();}public TestException(TestException te) {super(te.getMessage(),te);this.message = te.getMessage();}public TestException(String msg){super(msg);this.message = msg;}public String getMessage(){String result;if(this.message == null || "".equals(this.message)){result = super.getMessage();}else{result = this.message;}return result;}}

接着,在dubbo-provider-service里定义TestService

public interface TestService {public void test();}

然后在dubbo-provider-service-impl中定义TestServiceImpl

@Service("testService")
public class TestServiceImpl implements TestService{@Overridepublic void test() {throw new TestException("this is TestException...");}}

创建一个dubbo消费者工程

注:dubbo中Testservice相关的配置省略

在dubbo-consumer中新建TestController

@RestController
@RequestMapping("/test")
public class TestController {@Resource(name = "testService")private TestService testService;@RequestMapping("/test")public String test() {try {testService.test();} catch (Exception e) {System.out.println(">>>>>>>>>>" + e.getClass());e.printStackTrace();}return "SUCCESS";}}

启动这两个工程,访问dubbo-consumer中TestController的test方法,你就会发现控制台打印如下信息

注意,控制台中打印了“>>>>>>>>>>class java.lang.RuntimeException”

明明生产者中抛出的异常类型是TestException,怎么到了消费者中变成了RuntimeException呢

别急,我们先找下错误信息,往下拉,你会发现

就是这里对自定义异常进行了转换

就是这个invoke方法,我们来看一下它的注释

1.“directly throw if it’s checked exception”:意思就是说,如果该异常是检查型异常,则直接抛出

2.“directly throw if the exception appears in the signature”:大概意思是,如果接口的方法声明中抛出了该异常,则直接抛出

3.“for the exception not found in method’s signature, print ERROR message in server’s log”:意思是,如果接口的方法中没有声明该异常,则打印ERROR日志

4.“directly throw if exception class and interface class are in the same jar file”:大概意思是:如果异常类和接口类在同一个jar中,则直接抛出

5.“directly throw if it’s JDK exception”:意思是,如果是JDK中的异常,则直接抛出

6.“directly throw if it’s dubbo exception”:如果是dubbo的异常,则直接抛出

7.“otherwise, wrap with RuntimeException and throw back to the client”:否则,包装成RuntimeException抛出给客户端

根据错误信息同时结合注释,我们知道是走了7,你可能会觉得很坑,但仔细想一下,他这样做是很有必要的,因为走了第七步说明生产者定义的异常类在消费者上是找不到的,这时如果不把它包装成RuntimeException,那么在反序列化时就会出现问题,会无法序列化。

所以,最好的办法是:将异常类定义在公共的jar包中,然后生产者和消费者都引用它,同时生产者的接口声明中抛出该异常。


推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
author-avatar
娜娜的乖宝宝699
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有