Skip to content

[BUG] MapGeneralizer.Realize ignores m tags and silently drops renamed fields #3503

Description

@Oxidaner

✅ 验证清单

  • 🔍 我已经搜索过 现有 Issues,确信这不是重复问题

🚀 Go 版本

1.26.1

📦 Dubbo-go 版本

v 3.3.0

🖥️ 服务端配置

No response

💻 客户端配置

No response

🌐 协议配置

No response

📋 注册中心配置

No response

💾 操作系统

🍎 macOS

📝 Bug 描述

MapGeneralizer.Generalize uses the m struct tag as the generated map key,
but MapGeneralizer.Realize does not use the same tag when decoding the map.

Realize calls mapstructure.Decode with its default configuration.
mapstructure defaults to the mapstructure tag and only performs
case-insensitive field-name matching.

As a result, an m tag that genuinely renames a field, such as
UserID -> user_id, cannot be mapped back. The key is silently ignored,
the target field remains its zero value, and no error is returned.

This affects the default generic=true map generalization mode, including
generic request arguments, generic responses, and GenericService.InvokeWithType.

🔄 重现步骤

Create filter/generic/generalizer/m_tag_repro_test.go:

package generalizer_test

import (
	"reflect"
	"testing"

	"dubbo.apache.org/dubbo-go/v3/filter/generic/generalizer"
)

func TestMapGeneralizerMTagRoundTrip(t *testing.T) {
	type Payload struct {
		UserID string `m:"user_id"`
		Name   string
	}

	in := Payload{
		UserID: "42",
		Name:   "alice",
	}

	g := generalizer.GetMapGeneralizer()

	generalized, err := g.Generalize(in)
	if err != nil {
		t.Fatal(err)
	}

	t.Logf("generalized: %#v", generalized)

	realized, err := g.Realize(generalized, reflect.TypeOf(in))
	if err != nil {
		t.Fatal(err)
	}

	got := realized.(Payload)
	t.Logf("realized: %#v", got)

	if !reflect.DeepEqual(got, in) {
		t.Fatalf("round trip lost data: want %#v, got %#v", in, got)
	}
}

go test ./filter/generic/generalizer \
  -run TestMapGeneralizerMTagRoundTrip \
  -count=1 -v

### ✅ 预期行为

Payload{UserID: "42", Name: "alice"}

### ❌ 实际行为

generalized: map[string]interface {}{
    "name": "alice",
    "user_id": "42",
}
realized: Payload{
    UserID: "",
    Name: "alice",
}
round trip lost data

### 💡 可能的解决方案

_No response_

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions