How to parse json array having dynamic keys using Retrofit 2 - android

I am trying to fetch json response using retrofit 2. My json response looks like this :
[
0 : {
type : "video",
format : "mp4",
size : "10mb"
},
1 : {
type : "audio",
format : "mp3",
size : "10mb"
},
2 : {
type : "text",
format : "pdf",
size : "10mb"
}
]
How should my model class look like? I can't understand as it has dynamic keys.

This is not a valid Json as you can try that on https://jsonlint.com/ , you can change your response to :
[
{
"type":"video",
"format":"mp4",
"size":"10mb"
},
{
"type":"audio",
"format":"mp3",
"size":"10mb"
},
{
"type":"text",
"format":"pdf",
"size":"10mb"
}
]

first of all this is invalid/incomplete JSON. The valid version would look something like this
{
"items": [
{
"0": {
"type": "video",
"format": "mp4",
"size": "10mb"
}
},
{
"1": {
"type": "audio",
"format": "mp3",
"size": "10mb"
}
},
{
"2": {
"type": "text",
"format": "pdf",
"size": "10mb"
}
}
]
}
and it would safely deserialize to this
class Item{
String type;
String format;
String size;
}
class Response{
List<Map<Integer,Item>> items;
}
//....
Response response = new Gson().fromJson(yourJson, Response.class);
As an alternative solution, as I am sure you can't change the JSON format, change the [] to {} in your JSON string and deserialize it like this
Map fieldMap = (Map)new Gson().fromJson(json, Map.class);
it should give you a LinkedTreeMap of all your data

So, as people already said, if you change your json to be valid:
[
{
"type":"video",
"format":"mp4",
"size":"10mb"
},
{
"type":"audio",
"format":"mp3",
"size":"10mb"
},
{
"type":"text",
"format":"pdf",
"size":"10mb"
}
]
Then you can create your class, for instance:
public class Test {
public String type;
public String format;
public String size;
}
And then, with Gson:
Type testType = new TypeToken<ArrayList<Test>>(){}.getType();
ArrayList<Test> list = new Gson().fromJson(json, testType);
On the other hand, with retrofit2 you can get the Gson converter to do the job for you.

Related

Generate unique json object name gson in Kotlin

How would I be able to generate a new object based on the object names below. What I am trying to do here is that when there is no Object1, gson will generate Object1 with the values below and when there is Object1, gson will generate Object2 and so on.
{
"Object1": {
"Name": "Object1",
"Color": "Orange",
"Food": "Pizza"
},
"Object2": {
"Name": "Object2",
"Color": "Blue",
"Food": "Pineapple"
}
}
Generating an unique property in your class object means you could dynamically have a class lets say Example.
FoodData {
var object1 : Food?
var object2 : Food?
// And so on...
}
For me this seems like a structural problem. Your response should be specific to the data structure you have and need. A more acceptable approach would be:
[
{
"Name": "Object1",
"Color": "Orange",
"Food": "Pizza",
"someAttr" : "Object1"
},
{
"Name": "Object2",
"Color": "Blue",
"Food": "Pineapple",
"someAttr" : "Object2"
}
]
And then it would make more sense to have a list of food like :
FoodData {
var listFood: List<Food>?
}

Need to parse json array with gson. The items contain one property different on the basis of their type

I have a json array containing the list of widgets. But each widget has different data on the basis of the it's type. I need to parse this JSON by using the GSON android library. The approach i followed is : i have taken on response model containing the list of WidgetModel. The WidgetModel is of typed type. I have also defined the various types of data for the type.
For this i have created a gson deserializer but it is not working for me.
please check the json given below:
{
"page_title": "Invite And Earn",
"widgets": [
{
"type": "image",
"index": 0,
"title": null,
"ic_link": null,
"data": [
{
"link": "https://www.dike.li.us/images/sample-1.jpg"
}
]
},
{
"type": "text",
"index": 1,
"title": null,
"ic_link": null,
"data": [
{
"text": "Invite your friends. "
}
]
},
{
"type": "ref_code",
"index": 2,
"title": null,
"ic_link": null,
"data": [
{
"label": "Your Invite Code:",
"code": "AMANOV8KR"
}
]
},
{
"type": "line",
"title": null,
"ic_link": null,
"index": 3,
"data": [
{
"style": "full"
}
]
}
]
}
Deseirializer code is :
public class GsonDeserializer implements JsonDeserializer<WidgetRespModal> {
#Override
public WidgetRespModal deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
Type type = null;
switch (json.getAsJsonObject().get("type").getAsString()) {
case WidgetRespModal.WidgetType.IMAGE_WIDGET:
type = new TypeToken<ArrayList<ImageWidgetConfig>>() {
}.getType();
break;
case WidgetRespModal.WidgetType.LINE_WIDGET:
type = new TypeToken<ArrayList<LineWidgetConfig>>() {
}.getType();
break;
case WidgetRespModal.WidgetType.LINK_WIDGET:
type = new TypeToken<ArrayList<LinkWidgetConfig>>() {
}.getType();
break;
case WidgetRespModal.WidgetType.TEXT_WIDGET:
type = new TypeToken<ArrayList<TextWidgetConfig>>() {
}.getType();
break;
}
WidgetRespModal respModal = new WidgetRespModal();
if(json.isJsonObject()){
JsonObject respJson = json.getAsJsonObject();
respModal.setType(respJson.get("type").getAsString());
respModal.setIndex(respJson.get("index").getAsInt());
respModal.setIconLink(respJson.get("ic_link").getAsString());
respModal.setTitle(respJson.get("title").getAsString());
respModal.setConfig((List) context.deserialize(respJson.get("data").getAsJsonArray(), type));
}
return respModal;
}
}
Use Gson
Type type = new TypeToken<List<Student>>(){}.getType();
List<Student> students = gson.fromJson(json, type);
For further information check the post
https://stackoverflow.com/a/15011927/6742601
There is no point of creating deserializer for this simple use case.
Following line is enough
new Gson().toJson(strResponse, WidgetRespModal.class);

Retrofit2: Trying to Post Object which has multiple objects in it as Json?

I have Content class like that;
public class Content {
#SerializedName("id")
long id;
#SerializedName("content_type")
ContentType contentType;
long content_type_id;
#SerializedName("created_date")
Date createdDate;
#SerializedName("modified_date")
Date modifiedDate;
#SerializedName("components")
List<Component> components;
User owner;
These User, Component and ContentType are classes that I have created. I want to convert this class into Json like that;
{
"content_type": {
"id": 1,
"name": "Post",
"components": [
"text",
"longtext",
"video"
],
"component_names": [
"title",
"body",
"video"
]
},
"owner": {
"url": "http://localhost:8000/users/1/",
"id": 1,
"username": "admin",
"email": "admin#admin.com"
},
"owner_id": 1,
"content_type_id": 1,
"components": [
{
"component_type": "text",
"order": 1,
"type_data": {
"data": "Amber Run - Found"
}
},
{
"component_type": "longtext",
"order": 2,
"type_data": {
"data": "Warning sign"
}
},
{
"component_type": "video",
"order": 3,
"type_data": {
"data": "https://www.youtube.com/watch?v=Yj6V_a1-EUA"
}
}
]
}
If I send this raw Json data with PostMan, it works.
I am using this method in RetrofitApiService interface
#POST("group-contents/{group_id}/")
#FormUrlEncoded
Call<Content> postContent(#Path(value = "group_id", encoded = true) long groupId, #Body Content content);
However, I am getting this error
#Body parameters cannot be used with form or multi-part encoding.
How should I properly use retrofit to send Json objects like that?
You can send that as RequestBody, and also have to remove that #FormUrlEncoded
String json = new Gson().toJson(content) //Here content is your POJO class, that to be send.
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
#POST("group-contents/{group_id}/")
Call<Content> postContent(#Path(value = "group_id", encoded = true) long groupId, #Body RequestBody body);

Retrofit POJO is null but JSON is valid

Have been scratching my head on this one. The JSON Response is a valid one:
{
"MRData": {
"xmlns": "http://ergast.com/mrd/1.4",
"series": "f1",
"url": "http://ergast.com/api/f1/current/2.json",
"limit": "30",
"offset": "0",
"total": "1",
"RaceTable": {
"season": "2014",
"round": "2",
"Races": [
{
"season": "2014",
"round": "2",
"url": "https://en.wikipedia.org/wiki/2014_Malaysian_Grand_Prix",
"raceName": "Malaysian Grand Prix",
"Circuit": {
"circuitId": "sepang",
"url": "http://en.wikipedia.org/wiki/Sepang_International_Circuit",
"circuitName": "Sepang International Circuit",
"Location": {
"lat": "2.76083",
"long": "101.738",
"locality": "Kuala Lumpur",
"country": "Malaysia"
}
},
"date": "2014-03-30",
"time": "08:00:00Z"
}
]
}
}
}
The POJO for the response:
public class ApiResponse {
MRData mrdata;
public class MRData {
String xmlns;
String series;
String url;
String limit;
String offset;
String total;
RaceTable raceTable;
}
}
The apiResponse object is always null. Anyone can point out what is wrong with the POJO object here?
Thanks.
I see a couple of potential issues here:
You are defining a class inside another class; I have never seen it done like this. You might want to separate in two different files.
Your variable names on your POJO should match the variable names on the JSON response exactly. For example:
public class ApiResponse {MRData MRData;}
If you want your POJO's variables to be different than what the JSON sends back, you should use #SerlizedName.

get coordinates from JSON from google maps

I'm getting my position from an address, I use this website:
I get JSON data, but I dont know how to read it in my Android app.
{
"name": "plaza mayor 1 madrid España",
"Status": {
"code": 200,
"request": "geocode"
},
"Placemark": [ {
"id": "p1",
"address": "Plaza Mayor, 1, 28012 Madrid, España",
"AddressDetails": {
"Accuracy" : 8,
"Country" : {
"AdministrativeArea" : {
"AdministrativeAreaName" : "Comunidad de Madrid",
"SubAdministrativeArea" : {
"Locality" : {
"LocalityName" : "Madrid",
"PostalCode" : {
"PostalCodeNumber" : "28012"
},
"Thoroughfare" : {
"ThoroughfareName" : "Plaza Mayor, 1"
}
},
"SubAdministrativeAreaName" : "Madrid"
}
},
"CountryName" : "España",
"CountryNameCode" : "ES"
}
},
"ExtendedData": {
"LatLonBox": {
"north": 40.4164186,
"south": 40.4137207,
"east": -3.7053139,
"west": -3.7080118
}
},
"Point": {
"coordinates": [ -3.7066379, 40.4150359, 0 ]
}
} ]
}
How can I read the "coordinates" tag?
Thank you in advance!
parse it, to begin with, then access the various elements :
JSONObject response = new JSONObject(responseAsString);
JSONObject point = response.getJSONArray("Placemark").getJSONObject(0).getJSONObject("Point");
double lat = point.getJSONArray("coordinates").getDouble(0);
and so on
I would suggest using some sort of framwork to handle your Json data, here's a good aexample. Then you can handle your data as a regular object.
Sending and Parsing JSON Objects
Good luck!

Categories

Resources