1

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.

Smile
  • 3,832
  • 3
  • 25
  • 39
user12915845
  • 11
  • 1
  • 3
  • There is metadata at the beginning, can you add curly brackets at the beginning and at the end og the string and process that? – Popeye Feb 18 '20 at 00:53
  • Sorry, the braces were there, I missed it while copying it here. Edited the question with updated json. But getting same error. – user12915845 Feb 18 '20 at 01:09

3 Answers3

0

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.

theonlyrao
  • 416
  • 2
  • 13
  • I did that. So I created a POJO for Item and made the corresponding changes to Metadata. But still facing the same problem. And yes, I tried to parse the Json request without Item and its working fine. So the problem is definitely with Item, just dont know how to fix it. I am wondering why the exception says "Expected a string but was BEGIN_ARRAY" when I have defined it as ArrayList. I mean, why is it expecting a string? – user12915845 Feb 18 '20 at 03:07
0

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.

user12915845
  • 11
  • 1
  • 3
-1

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.

Smile
  • 3,832
  • 3
  • 25
  • 39