Cannot construct instance of `com.test.FilterModel`. No String-argument constructor/factory method to deserialize from String value

Tejas Shastri :

I have an implementation with Jackson Object mapper as follows:

public void getFilterTest(){
    String filterJSON = "{\"SelectOptions\":[{\"key\":\"status\",\"options\":[{\"sign\":\"eq\",\"value\":\"FAILED\"},{\"sign\":\"eq\",\"value\":\"ESCALATED\"}]}]}";
    ObjectMapper objectMapper = new ObjectMapper();
    FilterModel filters = null;
    try {
        filters = objectMapper.convertValue(filterJSON, FilterModel.class);
    }catch(Exception e) {
        e.printStackTrace();
    }
    assertNotNull(filters);}

On execution of convertValue I get the following error:

java.lang.IllegalArgumentException: Cannot construct instance of com.Test.FilterModel (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"SelectOptions":[{"key":"status","options":[{"sign":"eq","value":"FAILED"},{"sign":"eq","value":"ESCALATED"}]}]}') at [Source: UNKNOWN; line: -1, column: -1] at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3750) at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3668) at com.test.util.TestUnitCPIODataUtil.getFilterTest(TestUnitCPIODataUtil.java:71) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206) Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.test.FilterModel (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"SelectOptions":[{"key":"status","options":[{"sign":"eq","value":"FAILED"},{"sign":"eq","value":"ESCALATED"}]}]}') at [Source: UNKNOWN; line: -1, column: -1] at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343) at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032) at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371) at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1373) at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:171) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161) at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3745) ... 34 more

Here are my model classes: Filter Model:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"SelectOptions"
})
public class FilterModel {

@JsonProperty("SelectOptions")
private List<SelectOption> selectOptions = null;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("SelectOptions")
public List<SelectOption> getSelectOptions() {
return selectOptions;
}

@JsonProperty("SelectOptions")
public void setSelectOptions(List<SelectOption> selectOptions) {
this.selectOptions = selectOptions;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}

SelectOptions class:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"key",
"options"
})
public class SelectOption {

@JsonProperty("key")
private String key;
@JsonProperty("options")
private List<Option> options = null;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("key")
public String getKey() {
return key;
}

@JsonProperty("key")
public void setKey(String key) {
this.key = key;
}

@JsonProperty("options")
public List<Option> getOptions() {
return options;
}

@JsonProperty("options")
public void setOptions(List<Option> options) {
this.options = options;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}

Option model class:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"sign",
"value"
})
public class Option {

@JsonProperty("sign")
private String sign;
@JsonProperty("value")
private String value;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

@JsonProperty("sign")
public String getSign() {
return sign;
}

@JsonProperty("sign")
public void setSign(String sign) {
this.sign = sign;
}

@JsonProperty("value")
public String getValue() {
return value;
}

@JsonProperty("value")
public void setValue(String value) {
this.value = value;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}

I tried several solutions on other questions, but I could not find a solution. Seems like the whole JSON string is being considered a normal String. however, I'm not sure how to solve this. I need the FilterModel class as I expect more than 1 parameters, unlike the string in the above test case.

mfe :

You should call readValue method.

filters = objectMapper.readValue(filterJSON, FilterModel.class);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=148163&siteId=1