Tsukikage7 opened a new issue, #3167:
URL: https://github.com/apache/dubbo-go/issues/3167
## 背景
目前 dubbo-go 的泛化调用已经支持了核心功能(Map 序列化、Gson 序列化、Triple
协议等),但在实际使用中发现还有一些功能缺失,影响了跨语言调用的体验。
经过对比 Java dubbo 的实现,整理出以下需要补充的功能点。
## 现状
| 功能 | Java dubbo | dubbo-go |
|------|------------|----------|
| Map 序列化 (`generic=true`) | 支持 | 支持 |
| Gson 序列化 | 支持 | 支持 |
| Consumer/Provider Filter | 支持 | 支持 |
| Triple 协议支持 | 支持 | 支持 |
| GenericException 异常 | 支持 | 缺失 |
| 响应自动反序列化 | 支持 | 缺失 |
| generic.include.class 配置 | 支持 | 缺失 |
| protobuf-json 序列化 | 支持 | 代码有了但没接入 |
| Bean 序列化 | 支持 | 缺失 |
## 需要补充的功能
### 1. GenericException 异常处理
当 dubbo-go 调用 Java 服务时,如果 Java 端抛出业务异常,目前只能拿到一个字符串错误信息,原始的异常类型丢了。
比如 Java 端抛出 `UserNotFoundException`,dubbo-go 这边只能拿到 `"用户不存在"`
这个字符串,没办法知道这是什么类型的异常,也就没法做针对性的处理。
如果能拿到完整的异常信息就好了:
```go
type GenericException struct {
ExceptionClass string // 比如 "com.example.UserNotFoundException"
ExceptionMessage string // 比如 "用户不存在"
}
```
可以参考 Java dubbo 的 `GenericException.java`:
`dubbo-common/src/main/java/org/apache/dubbo/rpc/service/GenericException.java`
---
### 2. 响应自动反序列化
现在泛化调用返回的是 `map[string]any`,每次都要自己手动转成结构体,写起来挺烦的:
```go
result, _ := genericService.Invoke(ctx, "getUser", []string{"String"},
[]any{"123"})
m := result.(map[string]any)
user := &User{
Name: m["name"].(string),
Age: int(m["age"].(float64)),
}
```
要是能直接反序列化到结构体就方便多了:
```go
var user User
genericService.InvokeWithType(ctx, "getUser", []string{"String"},
[]any{"123"}, &user)
```
改动点在 `filter/generic/filter.go` 的 `OnResponse` 方法。
---
### 3. generic.include.class 配置
Java dubbo 有个 `generic.include.class` 配置,控制序列化时要不要带 `class` 字段:
- `true`:`{"class":"com.example.User", "name":"张三"}`
- `false`:`{"name":"张三"}`
如果 Java 端配置了 `generic.include.class=false`,dubbo-go 得能正确处理才行。
改动点:
- `common/constant/key.go` 加个常量
- `filter/generic/generalizer/map.go` 读配置控制行为
---
### 4. protobuf-json 序列化接入
`ProtobufJsonGeneralizer` 代码已经写好了(在
`filter/generic/generalizer/protobuf_json.go`),Triple 协议层也支持了,但 Filter
层没接上,导致实际用不了。
问题在 `filter/generic/util.go`:
```go
// isGeneric 只认 "true",不认 protobuf-json
func isGeneric(generic string) bool {
lowerGeneric := strings.ToLower(generic)
return lowerGeneric == constant.GenericSerializationDefault
}
// getGeneralizer 没有 protobuf-json 的 case
func getGeneralizer(generic string) (g generalizer.Generalizer) {
switch strings.ToLower(generic) {
case constant.GenericSerializationDefault:
g = generalizer.GetMapGeneralizer()
case constant.GenericSerializationGson:
g = generalizer.GetGsonGeneralizer()
// 缺少 protobuf-json
default:
g = generalizer.GetMapGeneralizer()
}
return
}
```
改动点:
- `filter/generic/util.go` 的 `isGeneric` 和 `getGeneralizer` 加上 protobuf-json
的支持
---
### 5. Bean 序列化
Java dubbo 支持 `generic=bean` 序列化,用 `JavaBeanDescriptor` 来描述对象。如果要调用的 Java
服务配了 `generic=bean`,现在 dubbo-go 处理不了。
可以参考 Java dubbo 的实现:
`dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanDescriptor.java`
## 相关文件
**dubbo-go 需要改动的文件**
| 功能 | 文件 |
|------|------|
| GenericException | `filter/generic/exception.go` (新建) |
| GenericException | `filter/generic/service_filter.go` |
| 响应反序列化 | `filter/generic/filter.go` |
| include.class | `common/constant/key.go` |
| include.class | `filter/generic/generalizer/map.go` |
| protobuf-json | `filter/generic/util.go` |
| Bean 序列化 | `filter/generic/generalizer/bean.go` (新建) |
**Java dubbo 参考文件**
| 功能 | 文件 |
|------|------|
| GenericException | `dubbo-common/.../rpc/service/GenericException.java` |
| 响应处理 | `dubbo-rpc/.../filter/GenericImplFilter.java` |
| include.class | `dubbo-common/.../utils/PojoUtils.java` |
| Bean 序列化 | `dubbo-common/.../beanutil/JavaBeanDescriptor.java` |
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]