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

如何用Jackson库反序列化无属性名的JSON数据?

问题:将JSON数组映射到Java对象(Jackson实现)

我无法控制的某个Web服务会返回如下格式的JSON响应:

[1737189665,1.0001,2.1123,"some string"]

该JSON是纯值数组,没有属性名。根据Web服务文档,数组元素依次对应timestamp、min、max、message这几个属性。

需要把这个JSON映射到如下的Result类对象:

@Data   // lombok
@Builder  // lombok
public class Result {
  Long timestamp;
  Double min;
  Double max;
  String message;
}

我的应用已经采用Jackson处理JSON,想咨询:

  • 实现这种映射的最佳方式是什么?
  • 我已经用自定义反序列化器实现了可行方案,但不确定是否必须这么做?

我的现有方案

我给Result类注册了自定义反序列化器:

@Data
@Builder
@JsonDeserialize(using = ResultDeserializer.class)
public class Result {
    // 属性定义同上
}

ResultDeserializer的代码如下:

public class ResultDeserializer extends StdDeserializer<Result> {

    // serialVersionId 和构造方法省略

    @Override
    public Result deserialize(JsonParser p, DeserializationContext ctx) throws IOException, JacksonException {

        JsonNode node = p.getCodec().readTree(p);
        Iterator<JsonNode> children = node.elements();
        
        return Result.builder()
            .timestamp(children.next().asLong())
            .min(children.next().asDouble())
            .max(children.next().asDouble())
            .message(children.next().asText())
            .build();
    }
}

映射代码:

String rawJson = "[1737189665,1.0001,2.1123,\"some string\"]"; // 实际从Web服务获取

ObjectMapper mapper = new ObjectMapper();
Result result = mapper.readValue(rawJson, Result.class);
// 注:原代码中把rawJson定义为Object[]是错误的,应为字符串类型

最佳实现方案:无需强制使用自定义反序列化器

方案1:使用@JsonFormat + @JsonProperty(index)(简洁首选)

Jackson原生支持将类与数组结构映射,通过@JsonFormat(shape = JsonFormat.Shape.ARRAY)注解即可实现,无需自定义反序列化器。

修改Result类如下:

@Data
@Builder
@NoArgsConstructor // 必须添加:Jackson需要无参构造实例化对象
@AllArgsConstructor // 配合@Builder及Jackson使用
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
public class Result {
    @JsonProperty(index = 0)
    Long timestamp;
    @JsonProperty(index = 1)
    Double min;
    @JsonProperty(index = 2)
    Double max;
    @JsonProperty(index = 3)
    String message;
}

映射代码直接使用Jackson标准API:

String rawJson = "[1737189665,1.0001,2.1123,\"some string\"]";
ObjectMapper mapper = new ObjectMapper();
Result result = mapper.readValue(rawJson, Result.class);

关键说明:

  • @JsonFormat(shape = JsonFormat.Shape.ARRAY)告诉Jackson将该类的实例序列/反序列化为数组结构;
  • @JsonProperty(index = N)指定每个属性对应数组的第N个元素,顺序必须与JSON数组一致;
  • 由于使用了@Builder,需要显式添加@NoArgsConstructor和@AllArgsConstructor,否则Jackson无法实例化对象。

方案2:保留自定义反序列化器(适合复杂场景)

如果你的映射逻辑涉及复杂处理(比如异常兜底、特殊类型转换、动态字段映射等),自定义反序列化器是更灵活的选择。但对于当前这种简单的顺序映射,@JsonFormat方案代码更简洁、维护成本更低,也更符合Jackson的原生设计。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:17:02