完善 yudao-spring-boot-starter-rpc 组件,增加 Dubbo 自定义的异常 Filter

This commit is contained in:
YunaiV 2022-06-25 22:10:47 +08:00
parent 917746a1a7
commit b8fb106aaf
6 changed files with 35 additions and 78 deletions

View File

@ -252,6 +252,11 @@
<artifactId>dubbo-cluster</artifactId> <!-- 兜底,保证在不引入 spring-cloud-starter-dubbo 时,注解等不报错 --> <artifactId>dubbo-cluster</artifactId> <!-- 兜底,保证在不引入 spring-cloud-starter-dubbo 时,注解等不报错 -->
<version>${dubbo.version}</version> <version>${dubbo.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId> <!-- 兜底,保证在不引入 spring-cloud-starter-dubbo 时,注解等不报错 -->
<version>${dubbo.version}</version>
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.cloud</groupId> <groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId> <artifactId>yudao-spring-boot-starter-rpc</artifactId>

View File

@ -38,10 +38,20 @@
<groupId>org.apache.dubbo</groupId> <groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId> <!-- 兜底,保证在不引入 spring-cloud-starter-dubbo 时,注解等不报错 --> <artifactId>dubbo-common</artifactId> <!-- 兜底,保证在不引入 spring-cloud-starter-dubbo 时,注解等不报错 -->
</dependency> </dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId> <!-- 兜底,保证在不引入 spring-cloud-starter-dubbo 时,注解等不报错 -->
</dependency>
<!-- --> <!-- -->
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>--> <!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-dubbo</artifactId>--> <!-- <artifactId>spring-cloud-starter-dubbo</artifactId>-->
<!-- </dependency>--> <!-- </dependency>-->
<!-- 工具相关 -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,28 +1,25 @@
package cn.iocoder.mall.dubbo.core.filter; package cn.iocoder.yudao.framework.rpc.core.dubbo;
import cn.iocoder.common.framework.exception.GlobalException; import cn.hutool.core.exceptions.ExceptionUtil;
import cn.iocoder.common.framework.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServerException;
import cn.iocoder.common.framework.util.ExceptionUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*; import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService; import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException; import javax.validation.ConstraintViolationException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import static cn.iocoder.common.framework.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.*;
import static cn.iocoder.common.framework.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
@Activate(group = CommonConstants.PROVIDER) // TODO 优化点设置下顺序 @Activate(group = CommonConstants.PROVIDER) // TODO 优化点设置下顺序
@Slf4j
public class DubboProviderExceptionFilter implements Filter, Filter.Listener { public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
private Logger logger = LoggerFactory.getLogger(DubboProviderExceptionFilter.class);
@Override @Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
return invoker.invoke(invocation); return invoker.invoke(invocation);
@ -55,14 +52,14 @@ public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
appResponse.setException(exception); appResponse.setException(exception);
} }
} catch (Throwable e) { } catch (Throwable e) {
logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e); log.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
} }
} }
} }
@Override @Override
public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) { public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) {
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e); log.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
} }
private boolean isReturnCommonResult(Invocation invocation) { private boolean isReturnCommonResult(Invocation invocation) {
@ -78,32 +75,31 @@ public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
if (!(returnType instanceof Class)) { if (!(returnType instanceof Class)) {
return false; return false;
} }
Class returnClass = (Class) returnType; Class<?> returnClass = (Class<?>) returnType;
return returnClass == CommonResult.class; return returnClass == CommonResult.class;
} }
/** /**
* 处理 Validator 校验不通过产生的异常 * 处理 Validator 校验不通过产生的异常
*/ */
private GlobalException constraintViolationExceptionHandler(ConstraintViolationException ex) { private ServiceException constraintViolationExceptionHandler(ConstraintViolationException ex) {
logger.warn("[constraintViolationExceptionHandler]", ex); log.warn("[constraintViolationExceptionHandler]", ex);
ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next(); ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next();
return new GlobalException(BAD_REQUEST.getCode(), return new ServiceException(BAD_REQUEST.getCode(),
String.format("请求参数不正确:%s", constraintViolation.getMessage())); String.format("请求参数不正确:%s", constraintViolation.getMessage()));
} }
/** /**
* 处理系统异常兜底处理所有的一切 * 处理系统异常兜底处理所有的一切
*/ */
private GlobalException defaultExceptionHandler(Throwable exception, Invocation invocation) { private ServerException defaultExceptionHandler(Throwable exception, Invocation invocation) {
logger.error("[defaultExceptionHandler][service({}) method({}) params({}) 执行异常]", log.error("[defaultExceptionHandler][service({}) method({}) params({}) 执行异常]",
invocation.getTargetServiceUniqueName(), invocation.getMethodName(), invocation.getArguments(), exception); invocation.getTargetServiceUniqueName(), invocation.getMethodName(), invocation.getArguments(), exception);
// 如果已经是 GlobalException 全局异常直接返回即可 // 如果已经是 GlobalException 全局异常直接返回即可
if (exception instanceof GlobalException) { if (exception instanceof ServerException) {
return (GlobalException) exception; return (ServerException) exception;
} }
return new GlobalException(INTERNAL_SERVER_ERROR) return new ServerException(INTERNAL_SERVER_ERROR).setMessage(this.buildDetailMessage(exception, invocation));
.setDetailMessage(this.buildDetailMessage(exception, invocation));
} }
private String buildDetailMessage(Throwable exception, Invocation invocation) { private String buildDetailMessage(Throwable exception, Invocation invocation) {

View File

@ -0,0 +1 @@
dubboExceptionFilter=cn.iocoder.yudao.framework.rpc.core.dubbo.DubboProviderExceptionFilter

View File

@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>common</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
<dependencies>
<!-- 通用相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 相关 -->
<!-- TODO 优化点Spring Cloud Alibaba Dubbo 的示例 -->
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-dubbo</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- 日志相关 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- 工具相关 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,2 +0,0 @@
dubboExceptionFilter=cn.iocoder.mall.dubbo.core.filter.DubboProviderExceptionFilter
dubboProviderRouterTagFilter=cn.iocoder.mall.dubbo.core.filter.DubboProviderRouterTagFilter