You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JSON空字符串反序列化为Java POJO的空List?

问题描述

我的POJO类Student包含List<String>类型的courseNames字段,定义如下:

public class Student {
    private List<String> courseNames;
    // getter、setter省略
}

当第三方传入数组格式的JSON时,反序列化正常:

{
    "courseNames": ["abc", "xyz"]
}

但第三方偶尔会传入空字符串:

{
    "courseNames": ""
}

此时希望courseNames被自动填充为空List。我尝试实现自定义JsonDeserializer但未完成,代码如下:

public class StringToEmptyListJsonDeserializer extends JsonDeserializer<List<String>> {

    @Override
    public List<String> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        if(jsonParser.getCurrentToken() != JsonToken.START_ARRAY) {
            return new ArrayList<>();
        }
        return // 此处该如何实现?
    }
}

请问如何委托默认的List反序列化器处理数组情况?或者有更优的解决方案?

解决方案

方案一:完善自定义JsonDeserializer,委托默认反序列化器

你可以通过DeserializationContext获取默认的List<String>反序列化器,在数组格式时委托它处理,非数组格式(比如空字符串)则返回空List。完整代码如下:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class StringToEmptyListJsonDeserializer extends StdDeserializer<List<String>> {

    protected StringToEmptyListJsonDeserializer() {
        super(List.class);
    }

    @Override
    public List<String> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        JsonToken currentToken = jsonParser.getCurrentToken();
        // 非数组类型(空字符串、null等)直接返回空List
        if (currentToken != JsonToken.START_ARRAY) {
            // 跳过当前无效token,避免后续解析出错
            jsonParser.skipChildren();
            return new ArrayList<>();
        }
        // 获取默认的List<String>反序列化器
        JavaType listType = deserializationContext.getTypeFactory()
                .constructCollectionType(List.class, String.class);
        JsonDeserializer<?> defaultDeserializer = deserializationContext.findRootValueDeserializer(listType);
        // 委托默认反序列化器处理数组
        @SuppressWarnings("unchecked")
        List<String> result = (List<String>) defaultDeserializer.deserialize(jsonParser, deserializationContext);
        // 确保返回非null的List
        return result != null ? result : new ArrayList<>();
    }
}

然后在Student类的字段上添加注解,指定使用该反序列化器:

public class Student {
    @JsonDeserialize(using = StringToEmptyListJsonDeserializer.class)
    private List<String> courseNames;
    // getter、setter省略
}

方案二:更简洁的注解+配置方案(无需自定义反序列化器)

如果你不想写自定义反序列化器,可以结合Jackson的配置和注解实现:

  1. 首先配置ObjectMapper,允许将空字符串视为null:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
  1. 然后在courseNames字段上添加@JsonSetter(nulls = Nulls.AS_EMPTY),将null值转换为空List:
public class Student {
    @JsonSetter(nulls = Nulls.AS_EMPTY)
    private List<String> courseNames;
    // getter、setter省略
}

这样当传入空字符串时,会先被转为null,再被自动替换为空List;传入数组时则正常反序列化。

方案三:通过Setter方法直接处理(简单但不够优雅)

你可以修改courseNames的Setter方法,直接处理不同类型的输入:

public class Student {
    private List<String> courseNames = new ArrayList<>();

    public void setCourseNames(Object courseNames) {
        if (courseNames instanceof List) {
            this.courseNames = (List<String>) courseNames;
        } else if (!(courseNames instanceof String) || !((String) courseNames).isEmpty()) {
            // 非空字符串或其他类型,可根据需求调整逻辑,比如抛出异常或清空List
            this.courseNames.clear();
        }
        // 空字符串情况保持当前空List
    }

    // getter省略
}

这种方式无需额外配置,但需要将Setter的参数改为Object类型,破坏了类型安全性,适合简单场景。

内容的提问来源于stack exchange,提问作者Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:42:54