Reputation: 228
I'm not sure how to deserialize array containing plain strings.I'm trying to parse the following JSON
{
"state":"RT",
"testMethod":"electronic",
"testElements":[
{
"testId":[
"UT_ITXref",
"Fed_ITXref"
]
},
"testStartDate",
"testEndDate",
"testDueDate"
]
}
I'm getting the following error:
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)
Here is what I did , I used @JsonCreator annotation to deserialize
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;
}
}
Should I write custom deserializer or Is there any way that I can use the jackson API for this. Any suggestions would be appreciated.
Upvotes: 0
Views: 962
Reputation: 3761
{
"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"
]
}
Did you intend the json to be interpreted as if it looked like the following?
{
"state": "RT",
"testMethod": "electronic",
"testElements": [
{
"testId": [
"UT_ITXref",
"Fed_ITXref"
]
},
{
testId: [
"testStartDate"
]
},
{
testId: [
"testEndDate"
]
},
{
testId: [
"testDueDate"
]
}
]
}
If so, you'll need to make a custom deserializer to detect whether the element in the array is an object or a string. If it's a string, you'll probably want to construct the TestElement
yourself.
Upvotes: 0
Reputation: 4120
Actually errors tells something.
JSON parser found that for testElements property there is an Array of Objects, but your Json file has mixed content.
first element is an object (I assume it is TestElement
class). Then parser creates that object with empty constructor and calls appropriate setters for its properties.
but...
second,third and forth elements are String, so error says that parser tries to find constrictor with String as argument.
So, you may try to make that constructor in TestElement
class and see will it work or not...
Do not forget to keep empty constructor as well.
I cannot guarantee it will work but, at least error says that.
BTW are you sure your Json object is correct? but not something like that?
{
"state":"RT",
"testMethod":"electronic",
"testElements":[
{
"testId":[
"UT_ITXref",
"Fed_ITXref"
]
}],
"testStartDate":"01-01-2017",
"testEndDate":"01-02-2017",
"testDueDate":"01-03-2017"
}
I'm a little confused because StartDate, EndDate, DueDate semantically look more like test attributes, not as elements in testElements array
Upvotes: 1