dubbo自动转换异常类型的坑

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

 

在某种特殊情况下,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{

	@Override
	public 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包中,然后生产者和消费者都引用它,同时生产者的接口声明中抛出该异常。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值