Home » Java » json – com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY-Exceptionshub

json – com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I am trying to parse the incoming Json (given below) to Java object using Gson. The Json request seems to be a valid one, but I am getting the following exception while parsing it.

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 5 column 19 path $.metadata.
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226) ~[gson-2.8.5.jar:?]
        at com.google.gson.Gson.fromJson(Gson.java:927) ~[gson-2.8.5.jar:?]

Incoming Json request :

{
    "metadata": {
        "salesId": "123",
        "promoCode": "2010",
        "items": [
            {
                "0": {
                    "productCode": "1234",
                    "total": 169900
                },
                "1": {
                    "productCode": "4567",
                    "total": 19900
                }
            }
        ]
    }
}

Parsing logic :

protected <T extends GenericModel> Optional<T> convertFromJson(final String json, final Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return Optional.empty();
        }
        return Optional.of(new Gson().fromJson(json, clazz));
    }

Java class :

public class Metadata {
    private String salesId;
    private String promoCode;
    private ArrayList<Object> items = new ArrayList<Object>();

    public String getSalesId() {
        return salesId;
    }

    public void setSalesId(String salesId) {
        this.salesId = salesId;
    }

    public String getPromoCode() {
        return promoCode;
    }

    public void setPromoCode(String promoCode) {
        this.promoCode = promoCode;
    }

    public ArrayList<Object> getItems() {
        return items;
    }

    public void setItems(ArrayList<Object> items) {
        this.items = items;
    }

    @Override
    public String toString() {
        return "Metadata{" +
                "salesId=" + getSalesId() +
                "promoCode=" + getPromoCode() +
                "items=" + getItems() +
                '}';
    }
}

Please note that Metadata.java is an inner class.

Have been trying to resolve the issue, but no luck. Could anyone let me know how to solve it? TIA.

How to&Answers:

I’d guess the problem is with the items object in the json you are trying to deserialize.

In the Metadata class items is an ArrayList<Object> but that doesn’t tell gson how to deserialize it.

Instead you should try creating another POJO for Item and then making the items an ArrayList<Item>. Something like this: Gson and deserializing an array of objects with arrays in it

You could check if items is the problem by commenting out that attribute and sending in just the salesId and promoCode.

Answer:

As your json has all data in metadata attribute, I created a new POJO having metadata field.

class ParentMetadata {
    private Metadata metadata;
    // getters and setters
}

And then parsed json to POJO using below code:

ParentMetadata parentMetadata = new Gson().fromJson(jsonStr, ParentMetadata.class);

This works fine for me.

Also, as items is of type ArrayList<Object>, during debugging I could see items are deserialized as List of LinkedTreeMap.

Answer:

I found out the issue and thought I’l post it here incase someone comes across the same issue. I cleaned the project and rebuild again and it worked fine. The issue was not with the code afterall. I read it on a thread regarding gson libraries and tried it. And it worked for me.