一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何在反序列化时将对象展开为列表形式

时间:2026-07-02 10:25:52 编辑:袖梨 来源:一聚教程网

使用 @JsonValue 注解可让 Jackson 将对象直接序列化为其内部列表值,从而避免嵌套对象结构,生成如 [ [123, 45.6], [789, 12.3] ] 这样的扁平数组格式。

使用 `@jsonvalue` 注解可让 jackson 将对象直接序列化为其内部列表值,从而避免嵌套对象结构,生成如 `[ [123, 45.6], [789, 12.3] ]` 这样的扁平数组格式。

在 Jackson 序列化中,当一个 Java 对象(如 DataPoint)被序列化为 JSON 时,默认会将其所有字段作为键值对输出为一个 JSON 对象。但本例中,我们希望 DataPoint 不以 { "dataPoint": [...] } 的形式出现,而是直接等价于其内部的二维数值列表——即每个 DataPoint 实例应被序列化为一个长度为 2 的数组 [long, double],并整体作为 dataPoint 字段的元素之一。

解决方案非常简洁:只需在 DataPoint 类中,将承载实际数据的字段(或其 getter 方法)标注 @JsonValue:

public class DataPoint {    private final List<Object> data;    public DataPoint(long date, double counts) {        this.data = List.of(date, counts);    }    @JsonValue  // ← 关键注解:声明此方法/字段为该对象的“JSON 值表示”    public List<Object> getData() {        return data;    }}

✅ 注意事项:

  • @JsonValue 只能标注一个非 void、非 void 泛型返回类型的方法或字段(推荐用 getter),且该方法必须是 public;
  • 若同时存在多个 @JsonValue,Jackson 会抛出异常;
  • 此注解仅影响序列化(Java → JSON),反序列化(JSON → Java)仍需配合 @JsonCreator 或默认构造器+setter(本例中因 data 是只读 final 字段,建议补充带参数的 @JsonCreator 构造器以支持反序列化);
  • List<?> 不推荐用于序列化场景,应明确使用 List<Object> 或更安全的 List<Number>(因 long 和 double 都是 Number 子类)。

完整可运行示例(含反序列化支持):

public class DataPoint {    private final List<Number> data;    public DataPoint(long date, double counts) {        this.data = List.of(date, counts);    }    @JsonCreator    public DataPoint(@JsonProperty("data") List<Number> data) {        if (data == null || data.size() != 2) {            throw new IllegalArgumentException("DataPoint requires exactly 2 numbers");        }        this.data = data;    }    @JsonValue    public List<Number> getData() {        return data;    }}

如此配置后,Entry 类无需任何额外修改,Jackson 即可正确生成目标 JSON 结构:

{  "name": "20070480",  "dataPoint": [    [1681792679186, 1096.0],    [1681792680186, 1147.0]  ]}

总结:@JsonValue 是 Jackson 提供的轻量级、声明式机制,专用于将对象“降维”为单一 JSON 值(如数组、字符串或数字),完美适用于此类“对象即数据元组”的场景,无需编写自定义序列化器,兼顾简洁性与可维护性。

热门栏目