1
votes

I am trying to parse below json response in retrofit/gson, specifically this json

{  
   "Coincheck":{  
      "BTC":[  
         "JPY"
      ]
   },
   "QuadrigaCX":{  
      "ETH":[  
         "CAD",
         "BTC"
      ],
      "BTC":[  
         "USD",
         "CAD"
      ]
   }
   // ... more data
}

I tried using Map< String, Map< String, List< String>>

public class ExchangeResp
{
    Map<String, Map<String, List<String>>> exchanges;

    public Map<String, Map<String, List<String>>> getExchanges()
    {
        return exchanges;
    }
}

but I always get response.body() as null. Do I need to create custom json desrializer implementing JsonDeserializer and pass to gson builder?

2
What is your retrofit Call<T> generic type T? Can you get make it Call<String> and get a json string as a response?pirho
@pirho I tried Call<String> and it worked if I use ScalarsConverterFactory, with GsonConverterFactory I got an exception Expected a string but was BEGIN_OBJECT. Earlier I was using Call<ExchangeResp> with GsonConverterFactory which didn't work, after I changed to Call<Map<String, Map<String, List<String>>>> it worked. Thanks for the help! I got two ways to parse reponse.Ajay

2 Answers

0
votes

Use your response class as

import com.google.gson.annotations.SerializedName;

import java.util.List;


public class Reposne {

@SerializedName("Coincheck")
private Coincheck coincheck;

@SerializedName("QuadrigaCX")
private QuadrigaCX quadrigaCX;

public Coincheck getCoincheck() {
    return coincheck;
}

public void setCoincheck(Coincheck coincheck) {
    this.coincheck = coincheck;
}

public QuadrigaCX getQuadrigaCX() {
    return quadrigaCX;
}

public void setQuadrigaCX(QuadrigaCX quadrigaCX) {
    this.quadrigaCX = quadrigaCX;
}

class Coincheck {
    @SerializedName("BTC")
    private List<String> btc;

    public List<String> getBtc() {
        return btc;
    }

    public void setBtc(List<String> btc) {
        this.btc = btc;
    }
}

class QuadrigaCX {
    @SerializedName("ETH")
    private List<String> eth;
    @SerializedName("BTC")
    private List<String> btc;

    public List<String> getEth() {
        return eth;
    }

    public void setEth(List<String> eth) {
        this.eth = eth;
    }

    public List<String> getBtc() {
        return btc;
    }

    public void setBtc(List<String> btc) {
        this.btc = btc;
    }
}

}
0
votes

Add the following three model classes

    public class Item {

@SerializedName("Coincheck")
@Expose
private Coincheck coincheck;
@SerializedName("QuadrigaCX")
@Expose
private QuadrigaCX quadrigaCX;

public Coincheck getCoincheck() {
return coincheck;
}

public void setCoincheck(Coincheck coincheck) {
this.coincheck = coincheck;
}

public QuadrigaCX getQuadrigaCX() {
return quadrigaCX;
}

public void setQuadrigaCX(QuadrigaCX quadrigaCX) {
this.quadrigaCX = quadrigaCX;
}

}

Coincheck.java

    public class Coincheck {

@SerializedName("BTC")
@Expose
private List<String> bTC = null;

public List<String> getBTC() {
return bTC;
}

public void setBTC(List<String> bTC) {
this.bTC = bTC;
}

}

QuadrigaCX

    public class QuadrigaCX {

@SerializedName("ETH")
@Expose
private List<String> eTH = null;
@SerializedName("BTC")
@Expose
private List<String> bTC = null;

public List<String> getETH() {
return eTH;
}

public void setETH(List<String> eTH) {
this.eTH = eTH;
}

public List<String> getBTC() {
return bTC;
}

public void setBTC(List<String> bTC) {
this.bTC = bTC;
}

}

and your network call using retrfit should be like

 call1.enqueue(new Callback<Item>() {
            @Override
            public void onResponse(Call<Item> call, Response<Item> response) {

            }

            @Override
            public void onFailure(Call<Item> call, Throwable t) {

            }


        });