使用Jackson ACCEPT_SINGLE_VALUE_AS_ARRAY从String反序列化ArrayList

时间:2012-10-08 02:42:57

标签: json serialization jackson

问题使用Jackson 2将数组反序列化为字符串

这与Deserialize ArrayList from String using Jackson

类似

传入的JSON(我无法控制)有一个元素'thelist',它是一个数组。 但是,有时它会以空字符串而不是数组形式出现:

例如。而不是“thelist”:[]
它来自“thelist”:“”

我在解析这两种情况时都遇到了问题。

'sample.json'文件正常工作:

{
   "name" : "widget",
   "thelist" : 
    [
       {"height":"ht1","width":"wd1"}, 
       {"height":"ht2","width":"wd2"}
    ]
}

课程:

public class Product { 
    private String name; 
    private List<Things> thelist; 
    // with normal getters and setters not shown
}

public class Things {
        String height;
        String width;
        // with normal getters and setters not shown
}

工作正常的代码:

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Test2 {
 public static void main(String[] args) 
    {
        ObjectMapper mapper = new ObjectMapper(); 
        Product product = mapper.readValue( new File("sample.json"), Product.class);
    }
}

但是,当JSON有一个空字符串而不是数组时,即。 “thelist”:“”
我收到这个错误:

com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [collection type; class java.util.ArrayList, contains [simple type, class com.test.Things]] from JSON String; no single-String constructor/factory method (through reference chain: com.test.Product["thelist"])

如果我添加此行(适用于Deserialize ArrayList from String using Jackson中的Ryan,并且看似文档支持),

mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

没有区别。

是否有其他设置,或者我是否需要编写自定义反序列化器?
如果是后者,是否有一个简单的例子,用Jackson 2.0.4做这个? 我是杰克逊的新手(和第一次海报,所以要温柔)。我做了很多搜索,但找不到一个好的工作实例。

2 个答案:

答案 0 :(得分:4)

问题是虽然单元素到数组工作,但您仍在尝试从(空)String转换为Object。我假设这是你面临的问题,虽然无一例外很难说。

但是还有DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT可以做到这一点,结合第一个功能。如果是这样,您将得到一个List,其中包含一个“空对象”,这意味着Things实例没有值。

理想情况下,如果您只启用ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,那么可能会执行您想要的操作:thelist属性的空值。

答案 1 :(得分:1)

嗨我正在解决类似的问题,当我得到这样的对象时

{  
   "name" : "objectname",
   "param" : {"height":"ht1","width":"wd1"}, 
}

来自外部系统所以“param”对我来说是对象,我试图去掉它。当在外部系统中定义此对象时,它可以正常工作。但是当外部系统中的OBJECT“param”未定义时,我得到空的ARRAY而不是空的OBJECT

{  
   "name" : "objectname",
   "param" : [], 
}

导致映射异常。 我通过创建自定义json反序列化器来解决它,它具有非常好的示例here并且对于类型I的测试使用类似

的类型
    ObjectCodec oc = jsonParser.getCodec();
    JsonNode node = oc.readTree(jsonParser);
    if (JsonNodeType.OBJECT == node.getNodeType()) {
        ParamObject result = new ParamObject();
        result.setHeight(node.get("height").asText());
        result.setWidth(node.get("width").asText());
        return result;
    }
    // object in MailChimp is not defined
    return null;