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

如何用Jackson将JSON数组反序列化为非集合类Java对象

问题描述

此前因实际需求从Gson切换至Jackson,原Gson代码可将如下结构的JSON数组反序列化为自定义PermissionOverwrites对象:

[
    {
        "id": "111111111111111111",
        "type": "0",
        "allow": "01010",
        "deny": "10101"
    }
]

原Gson实现逻辑:

JsonArray array = json.getAsJsonArray();
Map<Permissionable, Permissions> map = new HashMap<>();
 
for (JsonElement element : array) {
    JsonObject object = element.getAsJsonObject();
    Permissionable p = switch (object.get("type").getAsInt()) {
        case 0 -> new Permissionable.MockPermissionable(object.get("id").getAsLong()); 
        case 1 -> new Permissionable.MockPermissionable(object.get("id").getAsLong()); 
        default -> throw new JsonParseException("Unknown permissionable type");
    };
    Permissions perms = new Permissions(object.get("allow").getAsLong(), object.get("deny").getAsLong());
    map.put(p, perms);
}
 
return new PermissionOverwrites(map);

现使用Jackson时,仅持有JsonParser和DeserializationContext,不知如何解析数组完成相同功能,求实现方案。

补充PermissionOverwrites类代码:

@ToString
@EqualsAndHashCode
public class PermissionOverwrites {

    private Map<Permissionable, Permissions> overwrites;
    
    public PermissionOverwrites(Map<Permissionable, Permissions> overwrites) {
        this.overwrites = overwrites;
    }
    
    public PermissionOverwrites() {
        this.overwrites = new HashMap<>();
    }
    
    public Map<Permissionable, Permissions> getOverwrites() {
        return Collections.unmodifiableMap(overwrites);
    }
    
}
解决方案

在Jackson中,可通过自定义JsonDeserializer实现相同解析逻辑,核心是利用JsonParser遍历JSON数组元素,逐个解析构建目标对象:

1. 自定义PermissionOverwrites反序列化器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class PermissionOverwritesDeserializer extends JsonDeserializer<PermissionOverwrites> {

    @Override
    public PermissionOverwrites deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        // 将JsonParser转换为JsonNode数组
        JsonNode arrayNode = parser.getCodec().readTree(parser);
        if (!arrayNode.isArray()) {
            throw new IOException("Expected JSON array for PermissionOverwrites");
        }

        Map<Permissionable, Permissions> overwritesMap = new HashMap<>();

        for (JsonNode elementNode : arrayNode) {
            ObjectNode objectNode = (ObjectNode) elementNode;
            
            // 解析字段:JSON中为字符串类型,自动转为对应数值
            int type = objectNode.get("type").asInt();
            long id = objectNode.get("id").asLong();
            long allow = objectNode.get("allow").asLong();
            long deny = objectNode.get("deny").asLong();

            // 根据type创建Permissionable实例
            Permissionable permissionable = switch (type) {
                case 0, 1 -> new Permissionable.MockPermissionable(id);
                default -> throw new IOException("Unknown permissionable type: " + type);
            };

            // 构建Permissions并存入Map
            Permissions permissions = new Permissions(allow, deny);
            overwritesMap.put(permissionable, permissions);
        }

        return new PermissionOverwrites(overwritesMap);
    }
}

2. 注册反序列化器

有两种注册方式可选:

  • 方式一:类上注解标注
    直接在PermissionOverwrites类添加注解绑定反序列化器:
@ToString
@EqualsAndHashCode
@JsonDeserialize(using = PermissionOverwritesDeserializer.class)
public class PermissionOverwrites {
    // 原类代码保持不变
}
  • 方式二:ObjectMapper手动注册
    若无法修改目标类,可在初始化ObjectMapper时注册:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

SimpleModule module = new SimpleModule();
module.addDeserializer(PermissionOverwrites.class, new PermissionOverwritesDeserializer());

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);

// 后续使用该objectMapper完成反序列化
PermissionOverwrites overwrites = objectMapper.readValue(jsonString, PermissionOverwrites.class);

关键说明

  • 通过parser.getCodec().readTree(parser)将JsonParser转换为JsonNode,方便遍历数组元素
  • Jackson的asInt()/asLong()方法支持自动将字符串类型的数值转为对应基本类型
  • 异常处理逻辑与原Gson实现保持一致,遇到未知type直接抛出异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:55:39