Using Gson to Parse a JSON Array

How to Parse JSON Array with Gson

You can parse the JSONArray directly, don't need to wrap your Post class with PostEntity one more time and don't need new JSONObject().toString() either:

Gson gson = new Gson();
String jsonOutput = "Your JSON String";
Type listType = new TypeToken<List<Post>>(){}.getType();
List<Post> posts = gson.fromJson(jsonOutput, listType);

Using GSON to parse a JSON array and Object

I think ResultOsrm should hold list of Waypoint and class Waypoint will hold the data

public class ResultOsrm
{
public List<Waypoint> waypoints;
}

public class Waypoint
{
public int waypoint_index;
public int trips_index;
public String hint;
public String name;
public List<float> location;
}

waypoint_index is a variable in Waypoint, not a list by itself.

Using Gson in Kotlin to parse JSON array

You need to change parameter in your fromJson() function call like following:

val weatherList: List<WeatherObject> = gson.fromJson(stringReader , Array<WeatherObject>::class.java).toList()

You need to pass Array<WeatherObject>::class.java for class type and then convert result into List. No need to change registerTypeAdapter() function call.

Check following code:

fun getWeatherObjectFromJson(jsonStr: String): List<WeatherObject> {

var stringReader: StringReader = StringReader(jsonStr)
var jsonReader: JsonReader = JsonReader(stringReader)

val gsonBuilder = GsonBuilder().serializeNulls()
gsonBuilder.registerTypeAdapter(WeatherObject::class.java, WeatherDeserializer())
val gson = gsonBuilder.create()

val weatherList: List<WeatherObject> = gson.fromJson(stringReader , Array<WeatherObject>::class.java).toList()

return weatherList
}

Using GSON to parse a JSON array

Problem is caused by comma at the end of (in your case each) JSON object placed in the array:

{
"number": "...",
"title": ".." , //<- see that comma?
}

If you remove them your data will become

[
{
"number": "3",
"title": "hello_world"
}, {
"number": "2",
"title": "hello_world"
}
]

and

Wrapper[] data = gson.fromJson(jElement, Wrapper[].class);

should work fine.

Java Gson parse Json object to array

TL;DR: See "Using Deserializer" section at the bottom for parsing straight to array.


That JSON does not contain any arrays. An array would use the [...] JSON syntax.

Normally, a JSON object would map to a POJO, with the name in the name/value pairs mapping to a field of the POJO.

However, a JSON object can also be mapped to a Map, which is especially useful when the names are dynamic, since POJO fields are static.

Using Map

The JSON object with numeric values as names can be mapped to a Map<Integer, ?>, e.g. to parse that JSON to POJOs, do it like this:

class Root {
@SerializedName("Outer")
public Map<Integer, Outer> outer;
@Override
public String toString() {
return "Root[outer=" + this.outer + "]";
}
}
class Outer {
@SerializedName("Attr1")
public int attr1;
@SerializedName("Attr2")
public int attr2;
@Override
public String toString() {
return "Outer[attr1=" + this.attr1 + ", attr2=" + this.attr2 + "]";
}
}

Test

Gson gson = new GsonBuilder().create();
Root root;
try (BufferedReader in = Files.newBufferedReader(Paths.get("test.json"))) {
root = gson.fromJson(in, Root.class);
}
System.out.println(root);

Output

Root[outer={0=Outer[attr1=12345, attr2=67890], 1=Outer[attr1=54321, attr2=9876]}]

Get as Array

You can then add a helper method to the Root class to get that as an array:

public Outer[] getOuterAsArray() {
if (this.outer == null)
return null;
if (this.outer.isEmpty())
return new Outer[0];
int maxKey = this.outer.keySet().stream().mapToInt(Integer::intValue).max().getAsInt();
Outer[] arr = new Outer[maxKey + 1];
this.outer.forEach((k, v) -> arr[k] = v);
return arr;
}

Test

System.out.println(Arrays.toString(root.getOuterAsArray()));

Output

[Outer[attr1=12345, attr2=67890], Outer[attr1=54321, attr2=9876]]

Using Deserializer

However, it would likely be more useful if the conversion to array is done while parsing, so you need to write a JsonDeserializer and tell Gson about it using @JsonAdapter:

class Root {
@SerializedName("Outer")
@JsonAdapter(OuterArrayDeserializer.class)
public Outer[] outer;

@Override
public String toString() {
return "Root[outer=" + Arrays.toString(this.outer) + "]";
}
}
class OuterArrayDeserializer implements JsonDeserializer<Outer[]> {
@Override
public Outer[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// Parse JSON array normally
if (json.isJsonArray())
return context.deserialize(json, Outer[].class);

// Parse JSON object using names as array indexes
JsonObject obj = json.getAsJsonObject();
if (obj.size() == 0)
return new Outer[0];
int maxKey = obj.keySet().stream().mapToInt(Integer::parseInt).max().getAsInt();
Outer[] arr = new Outer[maxKey + 1];
for (Entry<String, JsonElement> e : obj.entrySet())
arr[Integer.parseInt(e.getKey())] = context.deserialize(e.getValue(), Outer.class);
return arr;
}
}

Same Outer class and test code as above.

Output

Root[outer=[Outer[attr1=12345, attr2=67890], Outer[attr1=54321, attr2=9876]]]

Parsing JSON array into java.util.List with Gson

Definitely the easiest way to do that is using Gson's default parsing function fromJson().

There is an implementation of this function suitable for when you need to deserialize into any ParameterizedType (e.g., any List), which is fromJson(JsonElement json, Type typeOfT).

In your case, you just need to get the Type of a List<String> and then parse the JSON array into that Type, like this:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

JsonElement yourJson = mapping.get("servers");
Type listType = new TypeToken<List<String>>() {}.getType();

List<String> yourList = new Gson().fromJson(yourJson, listType);

In your case yourJson is a JsonElement, but it could also be a String, any Reader or a JsonReader.

You may want to take a look at Gson API documentation.

Kotlin Gson parsing Json Object and Array

First you need to define two types that map to your JSON structure

class ApiParameterData(
val apiKey: String,
val baseUrl: String,
val requestData: List<RequestObject>
)

class RequestObject(
val lng: String,
val lat: String,
val rad: String,
val type: List<String>
)

Now simply parse it as

val apiData = Gson().fromJson(readJson, ApiParameterData::class.java)     // No need to add TypeAdapter

// To get requestData
val requestData = apiData.requestData
requestData.forEach {
print("${it.lng}, ${it.lat}, ${it.rad}, ${it.type})
}


Related Topics



Leave a reply



Submit