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

JSON对象反序列化为List时遇问题,寻求解决方法

解决JSON反序列化为List的问题

嘿,我来帮你搞定这个反序列化的麻烦!先拆解下你的JSON结构:外层是一个数组,里面的每个元素都包含returnValue字段,而returnValue又是一个存着业务数据的数组,还有MongoDB风格的$date时间格式——这俩点大概率是你卡壳的核心原因,下面分两种常用语言给你具体解决方案:

一、C# 环境(用Newtonsoft.Json)

1. 定义对应实体类

首先得把JSON里的字段映射到实体类上,注意字段名的对应,还有处理$date的特殊格式:

// 业务数据实体
public class FacilityRecord
{
    [JsonProperty("facility")]
    public string Facility { get; set; }

    [JsonProperty("recrd_desc")]
    public string RecordDescription { get; set; }

    [JsonProperty("update_time")]
    public DateTime UpdateTime { get; set; }

    [JsonProperty("control_num")]
    public int ControlNumber { get; set; }

    [JsonProperty("starttime")]
    public DateTime StartTime { get; set; }

    [JsonProperty("endtime")]
    public DateTime EndTime { get; set; }

    [JsonProperty("can_exchange_rate")]
    public int CanExchangeRate { get; set; }
}

// 外层包装类,对应JSON里的顶层数组元素
public class ApiResponse
{
    [JsonProperty("returnValue")]
    public List<FacilityRecord> ReturnValue { get; set; }
}

2. 自定义日期转换器处理$date

默认的序列化器不认识{"$date": 时间戳}这种格式,所以我们写个转换器把毫秒级时间戳转成DateTime:

public class UnixDateTimeConverter : JsonConverter<DateTime>
{
    public override DateTime ReadJson(JsonReader reader, Type objectType, DateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartObject)
        {
            var dateObj = JObject.Load(reader);
            if (dateObj.TryGetValue("$date", out var timestampToken) && timestampToken.Type == JTokenType.Integer)
            {
                return DateTimeOffset.FromUnixTimeMilliseconds((long)timestampToken).DateTime;
            }
        }
        throw new JsonSerializationException("无法解析MongoDB格式的日期");
    }

    public override void WriteJson(JsonWriter writer, DateTime value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        writer.WritePropertyName("$date");
        writer.WriteValue(new DateTimeOffset(value).ToUnixTimeMilliseconds());
        writer.WriteEndObject();
    }
}

3. 执行反序列化

配置好转换器后,就可以把JSON转成List了:

// 替换成你的完整JSON字符串
string jsonContent = "[{ \"returnValue\": [{ \"facility\": \"DRIO\", ... }] }]";

var serializerSettings = new JsonSerializerSettings
{
    Converters = { new UnixDateTimeConverter() }
};

// 先反序列化顶层数组
var apiResponses = JsonConvert.DeserializeObject<List<ApiResponse>>(jsonContent, serializerSettings);
// 提取returnValue里的业务数据列表
List<FacilityRecord> targetList = apiResponses.SelectMany(resp => resp.ReturnValue).ToList();

二、Java 环境(用Jackson)

1. 定义实体类

同样先映射字段,并用@JsonDeserialize指定自定义日期转换器:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.Date;

public class FacilityRecord {
    @JsonProperty("facility")
    private String facility;

    @JsonProperty("recrd_desc")
    private String recordDesc;

    @JsonProperty("update_time")
    @JsonDeserialize(using = MongoDateDeserializer.class)
    private Date updateTime;

    @JsonProperty("control_num")
    private int controlNum;

    @JsonProperty("starttime")
    @JsonDeserialize(using = MongoDateDeserializer.class)
    private Date startTime;

    @JsonProperty("endtime")
    @JsonDeserialize(using = MongoDateDeserializer.class)
    private Date endTime;

    @JsonProperty("can_exchange_rate")
    private int canExchangeRate;

    // 记得生成所有字段的getter和setter方法
}

// 顶层包装类
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

public class ApiResponse {
    @JsonProperty("returnValue")
    private List<FacilityRecord> returnValue;

    public List<FacilityRecord> getReturnValue() {
        return returnValue;
    }

    public void setReturnValue(List<FacilityRecord> returnValue) {
        this.returnValue = returnValue;
    }
}

2. 实现日期反序列化器

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 java.io.IOException;
import java.util.Date;

public class MongoDateDeserializer extends JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        JsonNode dateNode = parser.getCodec().readTree(parser);
        long timestamp = dateNode.get("$date").asLong();
        return new Date(timestamp);
    }
}

3. 完成反序列化

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.stream.Collectors;

public class DeserializeDemo {
    public static void main(String[] args) throws IOException {
        String jsonContent = "[{ \"returnValue\": [{ \"facility\": \"DRIO\", ... }] }]";
        ObjectMapper mapper = new ObjectMapper();
        
        // 反序列化顶层数组
        List<ApiResponse> apiResponses = mapper.readValue(jsonContent, new TypeReference<List<ApiResponse>>() {});
        // 提取业务数据列表
        List<FacilityRecord> targetList = apiResponses.stream()
                .flatMap(resp -> resp.getReturnValue().stream())
                .collect(Collectors.toList());
    }
}

额外提醒

  • 你的JSON末尾看起来是截断的(endtime": { "$date": 15445762... }]),一定要确保JSON是完整且格式正确的,不然反序列化会直接抛出格式错误异常。
  • 如果用其他序列化库(比如C#的System.Text.Json),核心思路还是:定义对应实体类 + 自定义转换器处理MongoDB日期格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:36:17