内容简介:在一个公共包里定义一个异常类,继承自RuntimeException。在服务提供者的Dubbo配置文件中添加下面的内容,主要就是自定义exceptionFilter,然后排出dubbo自带的exceptionFilter最重要的继承ExceptionFilter,然后重写invoke方法
在一个公共包里定义一个异常类,继承自RuntimeException。
public class BusinessException extends RuntimeException {
/**
* 异常code
*/
private String code;
public BusinessException() {
super();
}
public BusinessException(String message) {
super(message);
}
public BusinessException(String code, String message) {
super(message);
this.code = code;
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
public BusinessException(String code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
public BusinessException(Throwable cause) {
super(cause);
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
在服务提供者的Dubbo配置文件中添加下面的内容,主要就是自定义exceptionFilter,然后排出dubbo自带的exceptionFilter
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- http://dubbo.apache.org/schema/dubbo/dubbo.xsd 上面配置为这个一直报错,改为 http://code.alibabatech.com/schema/dubbo/dubbo.xsd -->
<!--用于配置当前应用信息,不管该应用是提供者还是消费者 -->
<dubbo:application name="dubbo-web-provide"/>
<!-- 用于配置连接注册中心相关信息 -->
<dubbo:registry address="zookeeper://localhost:2181" timeout="30000">
<!--配置 redis 连接参数 -->
<!--具体参数配置见com.alibaba.dubbo.registry.redis.RedisRegistry.class -->
<dubbo:parameter key="max.idle" value="10" />
<dubbo:parameter key="min.idle" value="5" />
<dubbo:parameter key="max.active" value="20" />
<dubbo:parameter key="max.total" value="100" />
</dubbo:registry>
<!--
最重要的就是下面的配置:自定义exceptionFilter,然后排出dubbo自带的exceptionFilter
payload 设置传输的最大值
-->
<dubbo:provider filter="dubboExceptionFilter,-exception" payload="123886080" ></dubbo:provider>
<!-- 用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受 -->
<dubbo:protocol name="dubbo" port="20880" accesslog="true" serialization="hessian2" />
<!-- 实现类 -->
<bean id="helloService" class="cn.ydstudio.dubbo.web.provide.serviceimpl.HelloServiceImpl" />
<bean id="goodsService" class="cn.ydstudio.dubbo.web.provide.serviceimpl.GoodsServiceImpl" />
<bean id="goodsService2" class="cn.ydstudio.dubbo.web.provide.serviceimpl.GoodsServiceImpl2" />
<bean id="goodsOrderServiceRemoteImpl" class="cn.ydstudio.dubbo.web.provide.serviceimpl.GoodsOrderServiceRemoteImpl" />
<!--定义暴露服务的接口,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心 -->
<!--每个接口都应定义版本号,为后续不兼容升级提供可能 -->
<!--ref:服务的真正实现类 -->
<dubbo:service interface="cn.ydstudio.dubbo.rpc.service.HelloService" ref="helloService" version="1.0.0" retries="1"/>
<dubbo:service interface="cn.ydstudio.dubbo.rpc.service.GoodsService" ref="goodsService" version="1.0.0" retries="1"/>
<dubbo:service interface="cn.ydstudio.dubbo.rpc.service.GoodsService" ref="goodsService2" version="2.0.0" retries="1"/>
<dubbo:service interface="cn.ydstudio.dubbo.rpc.service.GoodsOrderServiceRemote" ref="goodsOrderServiceRemoteImpl" version="1.0.0" retries="0" >
<dubbo:method name="querGoodsOrderList" timeout="1000000"/>
</dubbo:service>
<!--监控中心配置 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心。 -->
<!--<dubbo:monitor protocol="registry"></dubbo:monitor>-->
<!-- 直连监控中心服务器地址 -->
<!-- <dubbo:monitor address="localhost:6379"></dubbo:monitor> -->
</beans>
最重要的继承ExceptionFilter,然后重写invoke方法
package cn.ydstudio.dubbo.web.provide.filter;
import cn.ydstudio.common.tools.exception.BizException;
import cn.ydstudio.common.tools.exception.BusinessException;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.ReflectUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.rpc.*;
import com.alibaba.dubbo.rpc.filter.ExceptionFilter;
import com.alibaba.dubbo.rpc.service.GenericService;
import java.lang.reflect.Method;
/**
* 功能描述:<br/>
*
* @Author 刘洋【19037900】
* @Date 2019/4/30 18:02
*/
public class DubboExceptionFilter extends ExceptionFilter {
private final Logger logger;
public DubboExceptionFilter() {
this(LoggerFactory.getLogger(com.alibaba.dubbo.rpc.filter.ExceptionFilter.class));
}
public DubboExceptionFilter(Logger logger) {
this.logger = logger;
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
try {
Result result = invoker.invoke(invocation);
if (result.hasException() && GenericService.class != invoker.getInterface()) {
try {
Throwable exception = result.getException();
// 自定义的异常
if (exception instanceof BizException || exception instanceof BusinessException){
return result;
}
if (!(exception instanceof RuntimeException) && exception instanceof Exception) {
return result;
} else {
try {
Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
Class<?>[] exceptionClassses = method.getExceptionTypes();
Class[] arr$ = exceptionClassses;
int len$ = exceptionClassses.length;
for (int i$ = 0; i$ < len$; ++i$) {
Class<?> exceptionClass = arr$[i$];
if (exception.getClass().equals(exceptionClass)) {
return result;
}
}
} catch (NoSuchMethodException var11) {
return result;
}
this.logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
if (serviceFile != null && exceptionFile != null && !serviceFile.equals(exceptionFile)) {
String className = exception.getClass().getName();
if (!className.startsWith("java.") && !className.startsWith("javax.")) {
return (Result) (exception instanceof RpcException ? result : new RpcResult(new RuntimeException(StringUtils.toString(exception))));
} else {
return result;
}
} else {
return result;
}
}
} catch (Throwable var12) {
this.logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + var12.getClass().getName() + ": " + var12.getMessage(), var12);
return result;
}
} else {
return result;
}
} catch (RuntimeException var13) {
this.logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + var13.getClass().getName() + ": " + var13.getMessage(), var13);
throw var13;
}
}
}
然后在provider可以直接抛出异常,在consumer可以直接捕捉到。consumer服务消费端可以新建一个全局异常处理的控制器,可以格式化后输出给前端。
最后更新于 2019-05-20 20:12:02 并被添加「dubbo 自定义异常」标签,已有 1 位童鞋阅读过。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Laravel初级教程之服务提供者
- Laravel创建服务器提供者实例
- [ Laravel 5.7 文档 ] 底层原理 —— 服务提供者
- 干货 | 研究以太坊 2.0 中的状态提供者模型
- Laravel Providers——服务提供者的注册与启动源码解析
- 服务提供者(provider)与服务消费者(ribbon版本)-微服务架构
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机程序设计艺术卷1:基本算法(英文版.第3版)
Donald E.Knuth / 人民邮电出版社 / 2010-10 / 119.00元
《计算机程序设计艺术》系列著作对计算机领域产生了深远的影响。这一系列堪称一项浩大的工程,自1962年开始编写,计划出版7卷,目前已经出版了4卷。《美国科学家》杂志曾将这套书与爱因斯坦的《相对论》等书并列称为20世纪最重要的12本物理学著作。目前Knuth正将毕生精力投入到这部史诗性著作的撰写中。想了解本书最新信息,请访http://www-cs-faculty.stanford.edu/~knut......一起来看看 《计算机程序设计艺术卷1:基本算法(英文版.第3版)》 这本书的介绍吧!
JSON 在线解析
在线 JSON 格式化工具
Markdown 在线编辑器
Markdown 在线编辑器