dubbo接口统一异常处理的两种方式

Posted 伊人撩月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dubbo接口统一异常处理的两种方式相关的知识,希望对你有一定的参考价值。

  使用java开发没多久,对java体系的一些东西还不太熟悉。在项目开发过程中发现dubbo接口每个方法里都有一个try-catch的判断,都是一些重复性的工作,就想着能不能统一处理这些异常,找了一些资料果然可以,下面总结一下了解到的两种dubbo接口统一异常处理的方法方便以后查阅:
 
  第一种方法:dubbo提供了Filter接口,我们只需继承Filter接口实现invoke方法即可。
    1、实现Filter接口,实现invoke方法
 1 @Activate(group = Constants.PROVIDER)
 2 public class ExceptionFilter implements Filter {
 3     private static final Logger logger = LogManager.getLogger(ExceptionFilter.class);
 4 
 5     public Result invoke(Invoker<?> invoker, Invocation invocation) {
 6         Result result = null;
 7         try {
 8             result = invoker.invoke(invocation);
 9             if (result.hasException() && GenericService.class != invoker.getInterface()) {
10                 Throwable exception = result.getException();
11                 String data = String.format("\r\n[level]:Error,[createTime]:%s,[platform]:%s,[serviceName]:%s,[methodName]:%s,[inputParam]:%s", DateUtil.formatDateTime(new Date()), PlatformNameEnum.PAY, invoker.getInterface().getName(), invocation.getMethodName(), JSON.toJSONString(invocation.getArguments()));
12                 logger.error(data, exception);
13                 ResultVo resultVo = new ResultVo(false);
14                 resultVo.setResultCode(PayCenterErrorCodeEnum.PAY_ERR_100000.getCode());
15                 resultVo.setResultMessage(PayCenterErrorCodeEnum.PAY_ERR_100000.getMsg());
16                 //出现异常,打印日志后返回错误码
17                 return new RpcResult(resultVo);
18             }
19         } catch (RuntimeException e) {
20             String data = String.format("\r\n[level]:Error,[createTime]:%s,[platform]:%s,[serviceName]:%s,[methodName]:%s,[inputParam]:%s", DateUtil.formatDateTime(new Date()), PlatformNameEnum.PAY, invoker.getInterface().getName(), invocation.getMethodName(), JSON.toJSONString(invocation.getArguments()));
21             logger.error(data, e);
22         }
23         return result;
24     }
25 }
 
    2、在resources目录下添加纯文本文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter,内容如下:
   
          exceptionFilter=com.zcz.filter.ExceptionFilter
 
         3、修改dubbo的provider配置文件,在dubbo:provider中添加配置的filter,如下:
 
              <dubbo:provider filter="exceptionFilter"></dubbo:provider>
 
  第二种方法:aop拦截
    1、引入aop相关的jar包
        spring-aop、spring-aspects、aspectjrt
 
    2、编写统一异常处理AOP代码    
                     
 1 public class ExceptionAop {
 2     private static final Logger logger = LogManager.getLogger(ExceptionAop.class);
 3 
 4     public Object handlerControllerMethod(ProceedingJoinPoint pjp) {
 5         long startTime = System.currentTimeMillis();
 6 
 7         ResultVo result;
 8 
 9         try {
10             result = (ResultVo) pjp.proceed();
11             logger.info(pjp.getSignature() + "use time:" + (System.currentTimeMillis() - startTime));
12         } catch (Throwable e) {
13             result = handlerException(pjp, e);
14         }
15 
16         return result;
17     }
18 
19     private ResultVo handlerException(ProceedingJoinPoint pjp, Throwable e) {
20         ResultVo result = new ResultVo(false);
21         pjp.getArgs();
22 
23         // 已知异常
24         if (e instanceof BusinessException) {
25             result.setResultCode(Integer.parseInt(((BusinessException) e).getExceptionCode()));
26             result.setResultMessage(((BusinessException) e).getExceptionMsg());
27         } else {
28             logger.error(pjp.getSignature() + " error ", e);
29 
30             //TODO 未知的异常,应该格外注意,可以发送邮件通知等
31             result.setResultCode(PayCenterErrorCodeEnum.PAY_ERR_100000.getCode());
32             result.setResultMessage(PayCenterErrorCodeEnum.PAY_ERR_100000.getMsg());
33         }
34 
35         return result;
36     }
37 }
 
    3、配置Spring Aop的XML
 
1 <bean id="exceptionAop" class="com.zcz.pay.aop.ExceptionAop"/>
2     <aop:config>
3         <aop:pointcut id="target"
4                       expression="execution(* com.zcz.pay.api..*.*(..))"/>
5         <aop:aspect id="myAop" ref="exceptionAop">
6             <!-- 配置环绕通知 -->
7             <aop:around method="handlerControllerMethod" pointcut-ref="target"/>
8         </aop:aspect>
9     </aop:config>

 

以上是关于dubbo接口统一异常处理的两种方式的主要内容,如果未能解决你的问题,请参考以下文章

python-异常处理及异常处理的两种方式对比

spring的异常处理

异常处理

spring mvc 异常统一处理方式

使用mybatis的两种方式

Spring MVC统一异常处理