1

I have a json in which 1 key is coming as jsonArray if it has data otherwise it is coming as empty string. It is giving error while parsing in gson with retrofit.

  "section": "Technology",
  "subsection": "",
  "title": "Depiction of Amazon Stirs a Debate About Work Culture",
  "abstract": "Details of working conditions at Amazon led to a response from employees, relatives and friends.",
  "url": "http://www.nytimes.com/2015/08/19/technology/amazon-workplace-reactions-comments.html",
  "byline": "By THE NEW YORK TIMES",
  "item_type": "Article",
  "updated_date": "2015-08-18T07:35:33-5:00",
  "created_date": "2015-08-18T07:35:35-5:00",
  "published_date": "2015-08-19T04:00:00-5:00",
  "material_type_facet": "News",
  "kicker": "",
  "des_facet": [
    "Workplace Environment"
  ],
  "org_facet": [
    "Amazon.com Inc"
  ],
  "per_facet": "",
  "geo_facet": "",

des_facet , org_facet, per_facet, geo_facet are jsonArray but you can see that 2 are not having data so coming as empty string.

How to handle this scenario with retrofit +gson.

Json format can't be changed here at server.

is there any way I can achieve it in android?

Sandeep Agrawal
  • 546
  • 10
  • 27

3 Answers3

1

Ok so there are two option you can solve this

Option 1:

JSON which I used as a example

"des_facet": [
        "Workplace Environment"
    ],
    "org_facet": [
        "Amazon.com Inc"
    ],
    "per_facet": ["Akshay"],
    "geo_facet": ""

In your model class convert those variable to Object type

@Expose
    @SerializedName("geo_facet")
    private Object geo_facet;
    @Expose
    @SerializedName("per_facet")
    private Object per_facet;

then where you want to set data do the following

if (model != null)
        {
            if (model.getGeo_facet() != null || model.getGeo_facet() != "")
            {
                Object arr = model.getGeo_facet();
            }
            if (model.getPer_facet() !=null || model.getPer_facet()!= "")
            {
                Object arr = model.getPer_facet();
                if (arr!=null && arr.toString().length()>0)
                {
                    arr = arr.toString();
                    Log.d("akshay","arr= "+arr);
                    //Do your Stuff or Set data
                }
            }
        }

This is the output= 08-11 16:51:29.830 17951-17951/com.android.example D/akshay: arr= [Akshay]

Option 2:

Follow this which is a little bit complex

Option 3:

Write own custom Parsing like this and Handle your response accordingly

Akshay Katariya
  • 1,464
  • 9
  • 20
0

a json can have a single structure. From the code it is clear that the key is given with 2 types of data

Ideally, it should not give "" when no items. It should give null

Please change the data

If no items,

"des_facet"=null // this is the change on server side. No need to change it on app side

If it has items

"des_facet"=[
    "Workplace Environment"
  ]

instead of

If no items,

"des_facet"=""

If it has items

"des_facet"=[
    "Workplace Environment"
  ]
Viswanath Kumar Sandu
  • 2,230
  • 2
  • 17
  • 34
  • It was never mentioned "server change is not possible". And this is the standars way of API/JSON creation. this scenario can't be fixed from app side even in a hacky way. Because even the Object class can't be mapped with array or List as they are interfaces. So I don't see any way handling this on app side. – Viswanath Kumar Sandu Aug 11 '18 at 10:28
  • There is always a way my dear have a look at my answer, I handled it at app side – Akshay Katariya Aug 11 '18 at 11:31
0

You can use AutoValue with gson plugin and mark the field as nullable which will notify the Autovalue to make this field optional. AZs an example this is how you do it:

@AutoValue
public abstract class NewsResponse{

       public static TypeAdapter<NewsResponse> typeAdapter(Gson  gson){
               return new AutoValue_NewsResponse.GsonTypeAdapter(gson);
       }

       @SerializedName("api_status")
       public abstract String apiStatus();

       @SerializedName("api_text")
       public abstract String success();

       @Nullable
       @SerializedName("errors")
       public abstract ErrorDetails errorDetails();

        @SerializedName("news")
        public abstract List<NewsDetails> newsDetails();
}

you must import both of them see more info about importing at: AutoValue and AutoValue Gson Plugin

Ali Habbash
  • 777
  • 2
  • 6
  • 29