2025-12-25
一言
人生代代无穷已,江月年年只相似。 --- 《春江花月夜》 · 唐代 张若虚
Details
全文
春江潮水连海平,海上明月共潮生。滟滟随波千万里,何处春江无月明!
江流宛转绕芳甸,月照花林皆似霰。
空里流霜不觉飞,汀上白沙看不见。
江天一色无纤尘,皎皎空中孤月轮。
江畔何人初见月,江月何年初照人?
人生代代无穷已,江月年年只相似。
不知江月待何人,但见长江送流水。
白云一片去悠悠,青枫浦上不胜愁。
谁家今夜扁舟子,何处相思明月楼?
可怜楼上月徘徊,应照离人妆镜台。
玉户帘中卷不去,捣衣砧上拂还来。
此时相望不相闻,愿逐月华流照君。
鸿雁长飞光不度,鱼龙潜跃水成文。
昨夜闲潭梦落花,可怜春半不还家。
江水流春去欲尽,江潭落月复西斜。
斜月沉沉藏海雾,碣石潇湘无限路。
不知乘月几人归,落月摇情满江树。
Feign + Jackson + Java Record
null 字段在 JSON 序列化中未被忽略的问题分析与解决
一、问题背景
在使用 Java record 作为 Feign 请求体,并通过 Jackson 进行 JSON 序列化时,期望做到:
当 record 中某个字段为
null时,不将该字段写入 JSON
已知条件:
-
使用
@JsonInclude(JsonInclude.Include.NON_NULL) -
Feign Client 发送请求
-
record 中存在嵌套 record(
BareRequest.Condition)
但在 Feign DEBUG 日志中仍然看到:
"fromSource": null
二、问题复现代码(简化)
1️⃣ record 定义
@JsonInclude(JsonInclude.Include.NON_NULL)
public record BareRequest(
int mode,
String className,
boolean queryLike,
List<Condition> conditions
) {
public record Condition(
String column,
int option,
Object value,
Integer fromSource
) {}
}
2️⃣ 构造请求对象
var conditions = List.of(
new BareRequest.Condition("cmdb_approval_status", 2, "YES", null),
new BareRequest.Condition("operational_status", 7, "[Decommissioned]", 1),
new BareRequest.Condition("server_type", 2, "PM-BareMetal", null),
new BareRequest.Condition("support_group", 2, "XPO-", null)
);
var request = new BareRequest(0, "All", true, conditions);
client.search(1, 3000, request);
3️⃣ 实际序列化日志(问题现象)
{
"column": "cmdb_approval_status",
"option": 2,
"value": "YES",
"fromSource": null
}
三、问题根因分析(关键结论)
✅ 结论一:@JsonInclude 不会向下传递到嵌套类型
-
@JsonInclude(NON_NULL)只对当前声明的类型生效 -
不会自动作用于:
-
内部 record
-
List 中的元素类型
-
子 对象
-
因此:
-
BareRequest上的注解 对BareRequest.Condition无效 -
fromSource属于Condition,仍按默认规则序列化
这是 Jackson 的既定行为,不是 Feign 的问题,也不是 record 的问题
四、正确解决方案
方案一(最推荐):给嵌套 record 也加注解
@JsonInclude(JsonInclude.Include.NON_NULL)
public record BareRequest(
int mode,
String className,
boolean queryLike,
List<Condition> conditions
) {
@JsonInclude(JsonInclude.Include.NON_NULL)
public record Condition(
String column,
int option,
Object value,
Integer fromSource
) {}
}
✅ 效果:
fromSource == null 时,字段不会出现在 JSON 中