You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Gson将JSON反序列化为嵌套自定义Map并解决字段为空问题

问题原因

你定义的Match类中存在名为profiles的字段,但你的JSON结构中,match对应的对象下不存在名为profiles的层级,所有动态的username键都是直接挂载在match对象下的。Gson默认按照字段名做属性映射,找不到匹配的profiles字段就会默认赋值为null,且因为Gson对未知字段默认不抛出异常,所以不会有报错提示。

解决方法

下面分两种场景给出方案:

方案1:直接简化数据模型(最推荐,改动最小)

你完全不需要额外定义Match类,直接把外层模型中的match字段定义为Map<String, Profile>即可自动接收所有动态的username键值对:

// 注意类名不要用json,避免和关键字/变量名冲突,首字母大写符合Java规范
class MyJson {
    private String id;
    // 直接用Map接收match下所有动态key的键值对
    private Map<String, Profile> match;

    // 可选:添加getter、setter,如果字段为private需要加,或者配置Gson访问权限
    public Map<String, Profile> getMatch() { return match; }
    public void setMatch(Map<String, Profile> match) { this.match = match; }
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
}

class Profile{
    private String id;
    private String name;

    // 同样可选添加getter、setter
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

反序列化代码直接使用即可:

Gson gson = new Gson();
var myJson = gson.fromJson(data, MyJson.class);
// 访问数据:myJson.getMatch().get("username1") 即可拿到对应的Profile对象

方案2:必须保留Match类结构的场景

如果你因为业务逻辑必须保留Match类的层级结构,可以用两种方式实现:

方式A:让Match继承HashMap

class Match extends HashMap<String, Profile> {
    // 如有其他额外自定义字段可以在这里添加
}

// 外层模型保持原有结构
class MyJson {
    private String id;
    private Match match;
    // getter、setter
}

class Profile{
    private String id;
    private String name;
    // getter、setter
}

此时Match本身就是Map的实现类,反序列化后可以直接调用match.get("username1")获取数据。

方式B:给Match添加自定义反序列化适配器

如果你不想用继承,必须让Match类内部存在profiles字段存储所有数据,可以为Match类绑定自定义反序列化器:

import com.google.gson.*;
import java.lang.reflect.Type;
import java.util.Map;

// 自定义Match反序列化适配器
class MatchAdapter implements JsonDeserializer<Match> {
    @Override
    public Match deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        // 先把match下的所有内容反序列化为Map
        Type mapType = new com.google.gson.reflect.TypeToken<Map<String, Profile>>(){}.getType();
        Map<String, Profile> profiles = context.deserialize(json, mapType);
        // 组装成Match对象返回
        Match match = new Match();
        match.setProfiles(profiles);
        return match;
    }
}

// 给Match类绑定适配器
@JsonAdapter(MatchAdapter.class)
class Match {
    private Map<String,Profile> profiles;
    // getter、setter
    public Map<String, Profile> getProfiles() { return profiles; }
    public void setProfiles(Map<String, Profile> profiles) { this.profiles = profiles; }
}

注意事项

如果你的类字段声明为private且没有添加getter/setter,需要在构造Gson时配置允许访问私有字段:

Gson gson = new GsonBuilder()
        .excludeFieldsWithModifiers(java.lang.reflect.Modifier.STATIC, java.lang.reflect.Modifier.FINAL)
        .create();

内容的提问来源于stack exchange,提问作者slick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 21:15:07