Deserialize JSON to Java Object using Jackson : no String-argument constructor/factory method to deserialize from String value
Asked Answered
P

0

7

I have this serialized JSON given to me as string

"{\"UniqueId\":[\"69570d12-598d-4aca-abe9-4d0e7b286fe5\",\"949cd142-3eca-4fd8-b8ea-b681f65c69ca\"],\"CustomerOffers\":{\"137966\":[05],\"137986\":[11],\"137987\":[38]},\"Success\":true,\"ErrorMessages\":[\"No Error\"],\"ErrorType\":\"null\"}"

I need to deserialize it to Java object.

I created this object class

public class Data {

    public List<UUID> UniqueId;
    public Map<Integer, List<Integer>> CustomerOffers;
    public Boolean Success;
    public List<String> ErrorMessages;
    public String ErrorType;    

   // Usual Getters and Setters here
}

Then I created the method to grab the String and deserialize it, using com.fasterxml.jackson.databind.ObjectMapper

public class Deserializing {

public void processing(String input){

        ObjectMapper mapper = new ObjectMapper();
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

        try {

            // JSON string to Java object
            Data data = mapper.readValue(input, Data.class); //This returns exception
            System.out.println(data);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    
}

Then the main class to call the method.

public class Testing {

    @Test
    private void testing() throws ClassNotFoundException {
    Deserializing deserializing = new Deserializing();
    String rawData =  "\"{\\\"UniqueId\\\":[\\\"69570d12-598d-4aca-abe9-4d0e7b286fe5\\\",\\\"949cd142-3eca-4fd8-b8ea-b681f65c69ca\\\"],\\\"CustomerOffers\\\":{\\\"137966\\\":[05],\\\"137986\\\":[11],\\\"137987\\\":[38]},\\\"Success\\\":true,\\\"ErrorMessages\\\":[\\\"No Error\\\"],\\\"ErrorType\\\":\\\"null\\\"}\"";
    deserializing.processing(rawData);
    }

}

After I run it (using TestNG), I get this error message

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance ofData(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value

I am wondering, where could I do wrongly?

Thank You

PS: the original serialized JSON data that I get from the txt file looks like this "{\"UniqueId\":[\"69570d12-598d-4aca-abe9-4d0e7b286fe5\",\"949cd142-3eca-4fd8-b8ea-b681f65c69ca\"],\"CustomerOffers\":{\"137966\":[48],\"137986\":[48],\"137987\":[48]},\"Success\":true,\"ErrorMessages\":[\"No Error\"],\"ErrorType\":\"null\"}"
When I copy paste it to IntelliJ editor, escape string will need to be added (IntelliJ adds it automatically). If I grab the data straight from the txt file and use it, I just pass it to the method public void processing(String input) without worrying the escape characters. Not sure if this is correct though ...

Paperback answered 24/9, 2019 at 5:30 Comment(6)
you have \\\" in your string which make it looks like \" in json so it might be cause for exception replace all of them with single \"Granddaddy
Thanks for the comment. I added a note in the original posting. Thanks.Paperback
If you are worried about IntelliJ auto inserting these, then dont paste your content inside "" just directly paste the data you copied as it is already a string so you dont need to type qoutes yourselfGranddaddy
Also Jackson will not be able to parse numbers with leading zeros like 05. See thisLiebfraumilch
for unescaping this String you could use rawData = rawData.replace("\"", "").replace("\\", "\"");Liebfraumilch
Apparently the issue is caused by the raw data that was already escaped. The solution from @michalk works like charm. It needs to be un-escaped. May I ask what is the idea under the hood? As far as I know, those special characters always need to be escaped in Java before further processing. Why in this case, it is the other way around ? Is it Jackson's requirement? Thanks.Paperback

© 2022 - 2024 — McMap. All rights reserved.