
使用 @JsonValue 注解可让 Jackson 将对象直接序列化为其内部数据列表,从而避免嵌套对象结构,生成如 [ [1681792679186, 1096.0], [1681792680186, 1147.0] ] 这样的扁平数组格式。
使用 `@jsonvalue` 注解可让 jackson 将对象直接序列化为其内部数据列表,从而避免嵌套对象结构,生成如 `[ [1681792679186, 1096.0], [1681792680186, 1147.0] ]` 这样的扁平数组格式。
在 Jackson 序列化中,当一个 Java 类(如 DataPoint)被作为集合元素参与序列化时,默认会以 JSON 对象形式输出(例如 { "dataPoint": [123, 45.6] }),这与期望的纯二维数组格式 [[123, 45.6]] 不符。根本原因在于 Jackson 将整个 DataPoint 实例视为一个独立对象,而非其内部数据的“透明代理”。
解决方法非常简洁:只需在 DataPoint 中表示实际数据的字段(或其 getter 方法)上添加 @JsonValue 注解。该注解告诉 Jackson —— 此值即为该对象的唯一序列化表示,跳过对象包装,直接输出其内容。
以下是优化后的代码示例:
public class Entry {
private String name;
private List<datapoint> dataPoint;
// 构造函数、getter/setter 省略
}
public class DataPoint {
private final List<object> data; // 推荐使用具体类型,见下方说明
public DataPoint(long date, double counts) {
this.data = Arrays.asList(date, counts); // 或 List.of(date, counts)(Java 9+)
}
@JsonValue // ✅ 关键注解:声明 data 是该对象的 JSON 表示
public List<object> getData() {
return data;
}
}</object></object></datapoint>
⚠️ 注意事项:
- @JsonValue 只能标注一个非 void、非 void 返回类型的 getter 方法或字段(优先级:getter > 字段);
- 返回类型应为可直接序列化的类型(如 List>、Object[]、基本类型等),避免返回自定义复杂对象;
- 若需类型安全,建议将 data 声明为 List
或封装为 record DataPoint(long date, double counts) 并配合 @JsonValue 的 getter; - 此方案仅影响序列化(Java → JSON);反序列化(JSON → Java)仍需确保输入格式匹配(即传入的是长度为 2 的数组),否则需配合 @JsonCreator 自定义构造逻辑;
- @JsonUnwrapped 不适用此场景——它用于展开对象的 属性 到父级 JSON 对象中,而非将整个对象替换为其内部值。
最终序列化结果将严格符合目标结构:
{
"name": "20070480",
"dataPoint": [
[1681792679186, 1096.0],
[1681792680186, 1147.0]
]
}
无需编写自定义 JsonSerializer,也无需修改数据模型层级,是 Jackson 提供的轻量、标准且高效的标准解决方案。











