如何使用Jackson JSON反序列化枚举列表?

时间:2018-08-06 19:47:33

标签: java json enums jackson

我正在配置系统上。我希望能够从JSON文件加载配置值,并将其“自动”转换为所需的Java类型。我正在使用Jackson进行JSON解析。对于浮点数和字符串之类的原始类型,这没什么大不了的,但是我遇到了枚举的麻烦。

假设我有以下枚举:

public enum SystemMode
{
    @JsonProperty("Mode1")
    MODE1("Mode1"),
    @JsonProperty("Mode2")
    MODE2("Mode2"),
    @JsonProperty("Mode3")
    MODE3("Mode3");

    private final String name;

    private SystemMode(String name)
    {
        this.name = name;
    }

    @Override
    @JsonValue
    public String toString()
    {
        return this.name;
    }    
}

现在,假设我要使用以下JSON表示形式来表示给定配置变量的该枚举的值的列表:

{ 
    "Project" : "TEST",
    "System" : {
        "ValidModes" : ["Mode1", "Mode2"]
      }
}

我希望能够执行以下操作:

ArrayList<SystemMode> validModes = (ArrayList<SystemMode>) configurator.getConfigValue("/System/ValidModes");

作为参考,我的配置器类的getConfigValue方法本质上是Jackson JSON解析的一个瘦包装:

public Object getConfigValue(String JSON_String)
{
    JsonNode node = JsonNodeFactory.instance.objectNode().at(JSON_String);
    return objectMapper.convertValue(node, Object.class);
}

(真实方法具有一些异常检查,为清楚起见已将其省略)。

现在,当我调用上面的代码时,Jackson正确地推断出我想要一个ArrayList并填充它。但是,我没有获得SystemMode枚举的ArrayList,而是获得了Strings的ArrayList,并在尝试使用该列表时立即引发异常。我尝试了几种不同的方式来表示数据都无济于事。似乎无论我尝试什么,Jackson都想返回一个字符串列表而不是枚举列表。

所以我的问题是这个

我如何才能使Jackson(版本2.9.4)以与我的单个“ Object getConfigValue()”方法兼容的方式正确地反序列化枚举值列表? / strong>

1 个答案:

答案 0 :(得分:0)

以下内容将为您的枚举提供正确的绑定。

public List<SystemMode> getConfigValue(String path)
{
    JsonNode node = JsonNodeFactory.instance.objectNode().at(path);
    return objectMapper.convertValue(node, new TypeReference<List<SystemMode>>(){});
}

第二个选项是自己转换String的列表,例如:

List<SystemMode> result = jsonResult.stream().map(SystemMode::valueOf).collect(Collectors.toList());

第三种选择:

public <T>List<T> getConfigValue(String path, Class<T> type)
{
    JsonNode node = JsonNodeFactory.instance.objectNode().at(path);
    CollectionType toType = 
    objectMapper.getTypeFactory().constructCollectionType(List.class, type);
    return objectMapper.convertValue(node, toType);
}