ObjectWriter未遵循JsonInclude.Include.NON_EMPTY处理ArrayList问题
问题分析
你当前使用的@JsonInclude(JsonInclude.Include.NON_EMPTY)注解,对集合的判断逻辑是集合本身不为null且元素数量大于0就会被序列化。而你的代码中,当输入空字符串时,institutionIds被赋值为[""]——这个列表元素数量为1,不属于“空集合”范畴,所以注解无法过滤掉它。
解决方案
方案一:修改构造逻辑,提前处理空输入
在构造方法里判断输入字符串是否为空,为空时直接将institutionIds设为null或空列表,这样NON_EMPTY注解就能生效:
public class Request { @JsonInclude(JsonInclude.Include.NON_EMPTY) List<String> institutionIds; public Request(String institutionIds) { if (institutionIds == null || institutionIds.isEmpty()) { this.institutionIds = null; // 也可以用 Collections.emptyList() } else { this.institutionIds = List.of(institutionIds); } } public List<String> getInstitutionIds() { return institutionIds; } }
此时输入空字符串时,institutionIds为null,序列化后JSON中不会包含该字段。
方案二:使用自定义过滤规则
通过@JsonInclude的CUSTOM类型结合自定义过滤器,精准过滤掉包含单个空字符串的列表:
- 定义过滤器类:
public class EmptyStringListFilter { @Override public boolean equals(Object obj) { if (obj instanceof List) { List<?> list = (List<?>) obj; // 判断是否是仅包含一个空字符串的列表 return list.size() == 1 && list.get(0) instanceof String && ((String) list.get(0)).isEmpty(); } return false; } }
- 在字段上配置注解:
public class Request { @JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = EmptyStringListFilter.class) List<String> institutionIds; // 构造方法和getter保持不变 }
当institutionIds是[""]时,过滤器会判定该值需要被排除,JSON中就不会出现这个字段。
方案三:全局配置自定义序列化规则
如果需要多个地方复用这个逻辑,可以给ObjectMapper自定义序列化器:
- 实现针对
List<String>的序列化器:
public class EmptyStringListSerializer extends JsonSerializer<List<String>> { @Override public void serialize(List<String> value, JsonGenerator gen, SerializerProvider serializers) throws IOException { // 判断列表是否是仅包含一个空字符串 if (value != null && value.size() == 1 && value.get(0).isEmpty()) { // 不输出该字段 return; } // 正常序列化其他情况 gen.writeObject(value); } }
- 配置
ObjectMapper:
private static final ObjectWriter objectWriter = new ObjectMapper() .registerModule(new SimpleModule() .addSerializer(new EmptyStringListSerializer())) .writerWithDefaultPrettyPrinter();
这种方式无需修改实体类注解,全局生效。
内容的提问来源于stack exchange,提问作者Kaigo
相关产品推荐
相关产品推荐

