基于Filter的实现方案
package org.jeckxu.magical.core.dubbo.filter;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;
import org.jeckxu.magical.core.basic.exception.BusinessException;
import org.jeckxu.magical.core.basic.exception.ServiceException;
import org.jeckxu.magical.core.dubbo.exception.RpcTraceException;
import org.jeckxu.magical.core.tool.api.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Activate(group = CommonConstants.PROVIDER, order = 2)
public class MagicalDubboRpcExceptionFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(MagicalDubboRpcExceptionFilter.class);
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
Result appResponse = invoker.invoke(invocation);
if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
try {
Throwable e = appResponse.getException();
LOGGER.error(" [MAGICAL-DUBBO] Fail to MagicalDubboRpcExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
if (e instanceof BusinessException) {
BusinessException businessException = (BusinessException) e;
return AsyncRpcResult.newDefaultAsyncResult(R.fail(businessException.getResultCode().getCode(), businessException.getMessage()), invocation);
}
if (e instanceof ServiceException) {
ServiceException serviceException = (ServiceException) e;
return AsyncRpcResult.newDefaultAsyncResult(R.fail(serviceException.getResultCode().getCode(), serviceException.getMessage()), invocation);
}
if (e instanceof RpcTraceException) {
RpcTraceException rpcTraceException = (RpcTraceException) e;
return AsyncRpcResult.newDefaultAsyncResult(R.fail(rpcTraceException.getCode(), rpcTraceException.getMessage()), invocation);
}
} catch (Throwable e) {
LOGGER.error(" [MAGICAL-DUBBO] Fail to MagicalDubboRpcExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
return AsyncRpcResult.newDefaultAsyncResult(R.fail(65510, "远程服务调用发生异常"), invocation);
}
}
return appResponse;
}
}
org.apache.dubbo.rpc.Filter
magicalDubboRpcExceptionFilter=org.jeckxu.magical.core.dubbo.filter.MagicalDubboRpcExceptionFilter
优点:易于维护,便于扩展。
缺点:需要定义统一的业务异常及响应模型。