SpringBoot中POJO接收Kafka消息时List空值判定异常问题
问题根因
你遇到的现象本质是对JSON结构和Jackson注解的作用场景理解偏差导致的:
- 你收到的Kafka载荷里
assignedWorks:[{}]是长度为1的非空数组,里面的空JSON对象{}会被Jackson反序列化为一个AssignedWorkEBO实例,该实例的assignedWorkType和assignedWorkId字段均为null,但实例本身不是null,所以List的size为1、isEmpty返回false完全符合Java语法逻辑,和你预期的「空列表」不一样是因为你把「空数组」和「包含全空元素的数组」两个概念搞混了。 - 你用到的
@JsonInclude(JsonInclude.Include.NON_NULL)注解只作用于Java对象序列化为JSON字符串的阶段,会自动过滤掉值为null的字段不输出到JSON中,完全不影响JSON反序列化为Java对象的过程,所以这个注解和你遇到的问题没有关系。
解决方案
根据业务场景可以选择以下任意一种方案实现你的预期:
方案1:业务代码手动过滤(最简单通用)
拿到assignedWorks后先做一次有效值过滤,再做后续判断:
// 过滤掉所有字段均为null的无效AssignedWorkEBO实例 List<AssignedWorkEBO> validAssignedWorks = employee.getAssignedWorks().stream() .filter(work -> work.getAssignedWorkId() != null || work.getAssignedWorkType() != null) .collect(Collectors.toList()); // 此时的validAssignedWorks的size和isEmpty就符合你的预期 log.info("有效任务列表是否为空:{}", validAssignedWorks.isEmpty()); log.info("有效任务数量:{}", validAssignedWorks.size());
方案2:自定义Jackson反序列化器(自动处理,无需修改业务代码)
如果你希望反序列化阶段自动过滤掉全空的AssignedWorkEBO实例,可以自定义List类型的反序列化器:
第一步:编写自定义反序列化类
public class AssignedWorkListDeserializer extends StdDeserializer<List<AssignedWorkEBO>> { public AssignedWorkListDeserializer() { super(List.class); } @Override public List<AssignedWorkEBO> deserialize(JsonParser parser, DeserializationContext context) throws IOException { List<AssignedWorkEBO> originList = parser.readValueAs(new TypeReference<List<AssignedWorkEBO>>() {}); // 反序列化后直接过滤无效元素 return originList.stream() .filter(work -> work.getAssignedWorkId() != null || work.getAssignedWorkType() != null) .collect(Collectors.toList()); } }
第二步:给EmployeeEBO的assignedWorks字段绑定反序列化器
@Getter @Setter @Builder @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) @NoArgsConstructor @AllArgsConstructor public class EmployeeEBO implements Serializable { private static final long serialVersionUID = 1L; private String EmpId; // 绑定自定义反序列化器 @JsonDeserialize(using = AssignedWorkListDeserializer.class) private List<AssignedWorkEBO> assignedWorks; }
配置完成后,Jackson反序列化时会自动过滤掉全空的元素,直接返回符合你预期的List。
方案3:全局配置Jackson反序列化规则(适合多场景复用)
如果项目中多处都需要类似的「过滤全空POJO元素」的逻辑,可以给Jackson的ObjectMapper做全局配置,注册对应的反序列化规则,无需给每个字段单独加注解。
补充说明
如果后续AssignedWorkEBO新增了业务字段,你可以根据业务规则调整filter的判断条件,只要任意一个业务字段不为空就判定为有效元素即可。
内容的提问来源于stack exchange,提问作者Vikram Srinivasan
相关产品推荐
相关产品推荐

