JSON数组的反序列化

时间:2017-02-21 22:22:49

标签: java json jackson deserialization

我不知道如何反序列化包含普通字符串的数组。我正在尝试解析以下JSON

 {  
   "state":"RT",
   "testMethod":"electronic", 
   "testElements":[  
      {  
         "testId":[  
            "UT_ITXref",
            "Fed_ITXref"
         ]
      },
      "testStartDate",
      "testEndDate",
      "testDueDate"
   ]
}

我收到以下错误:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.test.rules.model.TestElements: no String-argument constructor/factory method to deserialize from String value ('testStartDate')
 at [Source: {"state":"RT","testMethod":"electronic","testElements":[{"testId":["UT_ITXref","Fed_ITXref"]},"testStartDate","testEndDate","testDueDate"}]}; line: 1, column: 247] (through reference chain: com.test.rules.model.TestRules["testElements"]->java.lang.Object[][1])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
    at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012)
    at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:370)
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:315)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1282)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:150)
    at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:196)
    at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:20)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:499)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:511)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:396)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1198)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1626)
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1220)

这是我做的,我使用@JsonCreator注释来反序列化

public class TestRules {

    private String state;   
    private String testMethod;  
    private TestElements[] testElements;    

     @JsonCreator
        public TaxRules(
          @JsonProperty("state") String  state,     
          @JsonProperty("testMethod") String testMethod,          
          @JsonProperty("testElements") TestElements[] testElements
          ) {
            this.state = state;         
            this.testMethod = testMethod;          
            this.testElements = testElements;          
        }   

}

 public class TestElements {
    private List<String> testId;
    private List<String> elements;  

    public List<String> getElements() {
            return elements;
        }
        public void setElements(List<String> elements) {
            this.elements = elements;
        }
        public List<String> getTestId() {
            return testId;
        }
        public void setTestId(List<String> testId) {
            this.testId = testId;
        }   

}

我应该编写自定义反序列化程序还是有任何方法可以使用jackson API。任何建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

实际上错误会说明一些事情。

JSON解析器发现,对于testElements属性,有一个对象数组,但是你的Json文件有混合内容。

第一个元素是一个对象(我假设它是TestElement类)。然后,解析器使用空构造函数创建该对象,并为其属性调用适当的setter。  但...

第二个,第三个和第四个元素是String,因此错误说解析器尝试使用String作为参数来查找constrictor。

所以,您可以尝试在TestElement类中创建该构造函数,看看它是否有效...... 不要忘记保留空构造函数。

我不能保证它会起作用,但至少错误说明了。

BTW你确定你的Json对象是正确的吗?但不是那样的吗?

{  
 "state":"RT",
 "testMethod":"electronic", 
 "testElements":[  
  {  
     "testId":[  
        "UT_ITXref",
        "Fed_ITXref"
     ]
  }],
  "testStartDate":"01-01-2017",
  "testEndDate":"01-02-2017",
  "testDueDate":"01-03-2017"
}

我有点困惑,因为StartDate,EndDate,DueDate在语义上看起来更像是测试属性,而不是testElements数组中的元素

答案 1 :(得分:0)

{
    "state": "RT",
    "testMethod": "electronic",
    "testElements": [
        {
            "testId": [
                "UT_ITXref",    // <-- this object is deserialized just fine
                "Fed_ITXref"
            ]
        },
        "testStartDate",     // <-- this is where the error is happening
        "testEndDate",
        "testDueDate"
    ]
}

您是否打算将json解释为如下所示?

{
    "state": "RT",
    "testMethod": "electronic",
    "testElements": [
        {
            "testId": [
                "UT_ITXref",
                "Fed_ITXref"
            ]
        },
        {
            testId: [
                "testStartDate"
            ]
        },
        {
            testId: [
                "testEndDate"
            ]
        },
        {
            testId: [
                "testDueDate"
            ]
        }
    ]
}

如果是这样,您需要创建一个自定义反序列化器来检测数组中的元素是对象还是字符串。如果它是一个字符串,您可能想要自己构造TestElement