2

with Jackson, I'm trying to properly deserialize a JSON which contains empty string as no value values. Herein an example:

{
  "code" : "REQ500",
  "description" : "Problem with Service",
  "params" : ""
}

and the bean I would get:

public final class MyError {

    @JsonProperty("code")
    private String code;

    @JsonProperty("description")
    private String description;

    @JsonProperty("params")
    private List<String> params;

    // [CUT]

    public void setParams(List<String> params) {
        this.params = params;
    }
}

Using ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, I've create an object mapper with

public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
    .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
    .registerModule(new SimpleModule().addDeserializer(LocalDate.class, new DateDeserializer()));

expecting to have params = null, but deserialization doesn't work. Herein the error I got:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot 
deserialize instance of `java.util.ArrayList` out of VALUE_STRING token
 at [Source: (String)"{
  "code" : "REQ500",
  "description" : "Problem with Service",
  "params" : ""
}"; line: 4, column: 14] (through reference chain: solutions.infinitec.fabrick.models.common.MyError["params"])

    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)

Any hints on how to solve this issue? Am I wrong somewhere?

Thank you in advance for suggestions.

2
  • did u try with implement setter method? Commented Jul 23, 2018 at 9:38
  • Yep, implemented. Nothing changed. Commented Jul 23, 2018 at 9:53

3 Answers 3

1

I tried it using ACCEPT_SINGLE_VALUE_AS_ARRAY and it works as expected.

ObjectMapper om = new ObjectMapper();
om.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

MyJson asString = om.readValue("{\n"
            + "  \"code\" : \"REQ500\",\n"
            + "  \"description\" : \"Problem with Service\",\n"
            + "  \"params\" : \"\"\n"
            + "}", MyError.class);

MyJson asArray = om.readValue("{\n"
            + "  \"code\" : \"REQ500\",\n"
            + "  \"description\" : \"Problem with Service\",\n"
            + "  \"params\" : [\"\"]\n"
            + "}", MyError.class);

The only thing you have to handle is the response containing just a single element in params which is empty.

Another way could be this definition of MyError:

public class MyError {

    @JsonProperty("code")
    private String code;

    @JsonProperty("description")
    private String description;

    private List<String> params;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<String> getParams() {
        return params;
    }

    @JsonProperty("params")
    private void setParams(JsonNode params) {
        if (params.isArray()) {
            this.params = new ArrayList<>();
            for(JsonNode child : params) {
                this.params.add(child.asText());
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

I'd try using

OBJECT_MAPPER.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

As shown in "Cannot deserialize instance of java.util.ArrayList"

2 Comments

Thanks for your answer. Can you please explain how this API solves the problem.
Already tried, it doesn't solve my issue given that, unfortunately, ObjectMapper::enable has the same behaviour of configuring ACCEPT_SINGLE_VALUE_AS_ARRAY equal to true.
0

Just implement a setter method which accept string:

public void setParams(String params) {
    this.params = null;
}

if want to accept array:

public void setParams(String[] params) {
    this.params = Arrays.asList(params);
}

5 Comments

when jackson deserialize it call no argument construct if there is no jsoncreator constructor. then call setter method.
u need to implement another method which accept array
Herein the error: line: 4, column: 13] (through reference chain: solutions.infinitec.fabrick.models.common.MyError["params"])
Doesn't work. I've got the following error: Cannot deserialize instance of 'java.lang.String' out of START_ARRAY token.
Interesting solution proposed by Halko Karr-Sajtarevic solves my issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.