关于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. git bash 报错bash: *: command not found

    默认安装的git bash某些功能是没有的,比如zip,在git bash下执行zip和unzip命令时会报错命令找不到,但值得庆幸的是,我们可以安装我们需要的命令,以下以zip命令为例,步骤如下: ...

  2. [Java] public, private, final and basic rules for naming.

    1. Access: public, private, protected public: Any other class can access a public field or method. ( ...

  3. cocos2d JS-(JavaScript) 几种循环遍历对象的比较

    通常我们会用循环的方式来遍历数组.但是循环是 导致js 性能问题的原因之一.一般我们会采用下几种方式来进行数组的遍历: 方式1: for in 循环: var arr = [1,2,3,4,5]; v ...

  4. SQL Server之获取下周一的日期

    今天项目中需要得到下周一的日期,故想到了一种解决办法,用slq语句解决了.当然实现方法肯定不只有这一种. -(select DATEPART(weekday,getdate())) /*下周一差几天 ...

  5. MySQL-UNIQUE

    什么是UNIQUE约束 可以使用 UNIQUE 约束确保在非主键列中不输入重复的值.尽管 UNIQUE 约束和 PRIMARY KEY 约束都强制唯一性,但想要强制一列或多列组合(不是主键)的唯一性时 ...

  6. MyBatis基础入门《六》Like模糊查询

    MyBatis基础入门<六>Like模糊查询 描述: 未改动的文件,不再粘贴出来.项目中SQL的xml映射文件重要标签如下: mapper namespace cache 配置给定命令空间 ...

  7. Oracle的下载安装教程以及所出现的问题

    1.下载地址 64位 https://www.oracle.com/technetwork/database/enterprise-edition/downloads/112010-win64soft ...

  8. 关于js语句的分号

    我在使用js的时候可能发现一个现象:js语句结尾有时候有分号,有时候没有,没有的时候js代码也是能正确执行的. 到底要不要写分号?QAQ 转自博客园@winter-cn JavaScript自动加分号 ...

  9. Sitecore CMS中配置项目图标

    在Sitecore中,图标通常用于通过各种不同的模板类型快速区分项目.文章可能使用红色图标,而列表页面可能使用蓝色.项目上设置的图标可以在内容树中看到,也可以在选择项目时在内容编辑器的顶部看到. 从功 ...

  10. 加载MySQL、Oracle、SQL Server 2000、SQL Server 2005及以上版本 的加载数据库驱动程序

    2018-11-04  20:00:59 开始 //getConnection(String url, String user, String password) //url:连接数据库的URL 3 ...