关于dubbo的Exception堆栈被吃处理,网上已经有比较多的解决方法,在我们的应用场景中,不希望RPC调用对方抛出业务exception,而是通过Resp中的errorCode,errorMsg来处理,例如有如下的定义:

    @Override
public ResultModel<String> createExpress(CreateExpressDTO dto) {
// 参数验证
String group = "";
if (StringUtils.isNotBlank(dto.getPartyId())) {
group = Group.PARTY_TYPE_PARTY;
} else if (DictCons.BANK_ACCOUNT_TYPE__PUBLIC.equals(dto.getBankAccountType())) {
group = Group.PARTY_TYPE_NOT_PARTY_PUB;
} else {
group = Group.PARTY_TYPE_NOT_PARTY_PRI;
}
ValidationResult validationResult = ValidationUtils.validateEntity(group, dto);
if (!validationResult.isSuccess()) {
return new ResultModel<>(ErrorCons.ERR_BS_BAD_PARAM,
FastJsonUtil.serializeFromObject(validationResult.getErrorPair()));
}
此处省去N行。。。。。

假设createExpress执行异常的时候,我们希望错误通过ResultModel<String>而不是RuntimeException回去,dubbo的exceptionfilter不符合我们的要求,如果要改动的话,需要到序列化层进行修改(原来在自己开发的RPC框架上就是这么处理的)。这种情况,只能借助AOP,如下:

package tf56.lf.common.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import tf56.lf.base.ResultModel;
import tf56.lf.base.metadata.err.ErrorCons;
import tf56.lf.common.exception.LfException; import com.alibaba.fastjson.JSON; @Aspect
public class ServiceAroundAdvice implements InitializingBean { private static final Logger logger = LoggerFactory.getLogger(ServiceAroundAdvice.class); @Around("execution(* tf56.lf.*.service..*(..))")
public Object processDubboService(ProceedingJoinPoint jp) throws Throwable{
long begin = System.currentTimeMillis();
logger.info("开始执行" + jp.getSignature() + "参数:" + JSON.toJSONString(jp.getArgs()));
Object result = null;
try {
result = jp.proceed();
} catch (Exception e) {
logger.error("",e);
Class<?> clz = ((MethodSignature)jp.getSignature()).getMethod().getReturnType();
if ("void".equals(clz.getName())) {
return result;
} ResultModel<?> resultModel = ((ResultModel<?>)clz.newInstance());
if (e instanceof LfException) {
resultModel.setCode(((LfException) e).getCode());
resultModel.setMsg(((LfException) e).getErrorInfo());
} else {
resultModel.setCode(ErrorCons.ERR_FAIL);
}
result = resultModel;
}
long end = System.currentTimeMillis();
logger.info("完成执行" + jp.getSignature() + ",共" + (end - begin) + "毫秒!");
return result;
} @Override
public void afterPropertiesSet() throws Exception {
logger.info("加载" + this.getClass().getCanonicalName() + "成功!");
}
}

增加配置如下:

<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <bean class="tf56.lf.common.advice.ServiceAroundAdvice"></bean>
<aop:aspectj-autoproxy proxy-target-class="true" />

这样就可以保证所有的Exception都会被优雅的处理,同时泛型也都能恰当的被处理。

dubbo rpc调用抛出的Exception处理的更多相关文章

  1. 记录一次dubbo不能正常抛出特定异常

    BUG场景 今天同事的代码中出现一个问题,让我帮忙排查一下.原代码大致如下 dubbo服务消费者: @Resource private IPayWayService payWayService; @R ...

  2. 【M12】了解“抛出一个exception”与“传递一个参数”或“调用一个虚函数”之间的差异

    1.方法参数的声明语法和catch语句的语法是一样的,你可能会认为主调方法调用一个方法,并向其传递参数,与抛出一个异常传递到catch语句是一样的,是的,有相同之处,但也有更大的不同. 2.主调方法调 ...

  3. Dubbo RPC调用参数校验---错误message自动返回

    Dubbo 的RPC调用中Consumer 和 Provider端都可以对调用的方法做传参验证,参数的验证可以通过JSR303规范 (Java Specification Requests) 提到的 ...

  4. dubbo rpc调用,接收到的bean为null原因?

    前几天对接公司内部其他部门的系统,用dubbo调用,dubbo看起来很简单,但是却让我们调试了好久啊! 下面是调试纪录: 1. 调用该服务时,直接调不通,查看错误为 no provider ? 然后就 ...

  5. VS2013 抛出 stackoverflow exception 的追踪

    本公司使用VWG.Caslte ActiveRecord.CSLA.net .Quantz.net 等组件做为公司的开发基础,自2007年以来,一直工作正常,但最近(2015.12月)以来,打开MDA ...

  6. 从constructor中抛出exception后,constructor会返回null吗?

    刚才琢磨这个问题主要是在想,如果constructor抛出了exception,那么返回的object是什么一个情况呢?如果我这个object中有一些关键的资源没有初始化,比如说Database co ...

  7. Spring异常抛出触发事务回滚

    Spring.EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚 /** * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*) ...

  8. JAVA异常的捕获与抛出原则

    在可能会出现exception的地方,要使用try-catch或者throws或者两者都要.我的判断依据是:如果对可能出现的exception不想被外部(方法的调用者)知道,就在方法内部try-cat ...

  9. 【开发技术】java异常的捕获与抛出原则

    在可能会出现exception的地方,要使用try-catch或者throws或者两者都要.我的判断依据是:如果对可能出现的exception不想被外部(方法的调用者)知道,就在方法内部try-cat ...

随机推荐

  1. python中的filter、map、reduce、apply用法

    1. filter 功能: filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数. 调用: filter(function,seq ...

  2. vue中使用hotcss--stylus

    页面中一直闪动这个. 后面改成scss后还是这样.还不知道原因

  3. Jmeter获取响应结果中参数出现的次数

    在测试中,有时候会遇到要统计响应结果中某个参数出现了多少次,如果量级很大,一个一个数不太现实,下面讲一下实现自动打印出该参数出现的次数的方法. 例如我的响应信息为:{"ip":&q ...

  4. iOS UI进阶-1.0 Quartz2D

    概述 Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统.Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF ...

  5. 注解(Annotation)

    注解(Annotation)很重要,未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是 ...

  6. HDU 2256 Problem of Precision(矩阵)

    Problem of Precision [题目链接]Problem of Precision [题目类型]矩阵 &题解: 参考:点这里 这题做的好玄啊,最后要添加一项,之后约等于,但是有do ...

  7. C-Cow Sorting (置换群, 数学)

    Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a uniqu ...

  8. JDBC操作数据库步骤

    2018-11-04  20:23:24开始写 1.加载驱动程序(Class.forName) 2.建立连接获取数据库连接对象(DriverManager.getConnection) 3.向数据库发 ...

  9. maven编译不通过:软件包com.sun.org.apache.xml.internal.security.utils.Base64 不存在

     问题:代码中使用了sun公司的第三方私有库,导致编译不通过 maven打包异常:软件包com.sun.org.apache.xml.internal.security.utils.Base64 不存 ...

  10. ODBC数据库

    ODBC数据源全称是开放数据库互连(Open Database Connectivity),在微软公司开放的数据库结构中的一部分,其实是一个应用程序的接口,主要用于提供数据库的编写应用程序的能力.