The response you are getting is a JSON object and not an array of objects. This error happens because an array is expected at the beginning of JSON (starting with [
), since you pass as type to deserialize a list of Pluviometro
, but there is {
, ie the beginning of an object.
There are some ways you can do this, I'll name just two.
The simplest way is to define another object, let's call it CEMADENResponse
, which will add a list of rain gauges. As in the response the name of the object is cemaden
, to be more readable the object we need to speak the name the attribute to GSON. So this object should look like this:
public class CEMADENResponse {
@SerializedName("cemaden")
private List<Pluviometro> pluviometros;
// getter e setter
}
You can call the list of cemaden
and not pluviometros
, if you want, and remove the annotation @SerializedName
, if you prefer.
Created the object, to deserialize to an instance of CEMADENResponse
, just do something like this:
final String jsonResponse = sendGet("http://150.163.255.240/CEMADEN/resources/parceiros/GO/1");
final Gson gson = new Gson();
final CEMADENResponse response = gson.fromJson(jsonResponse, CEMADENResponse.class);
From there, just retrieve the list of rain gauges and do what you need, for example print the value of all of them:
final List<Pluviometro> pluviometros = response.getPluviometros();
for (Pluviometro pluviometro : pluviometros) {
System.out.println("codestacao: " + pluviometro.getCodestacao());
System.out.println("latitude: " + pluviometro.getLatitude());
System.out.println("longitude: " + pluviometro.getLongitude());
// outros atributos
}
That will generate something like this according to the result:
codestacao: 520310401A
latitude: -16.196
longitude: -52.546
The second way is to use a custom deserializer. Starting with your attempt to return a list of rain gauges soon, let's have the custom deserializer then return a List<Pluviometro>
.
The work here is a bit larger, as we should get the JSON
element and read each property. It should look something like this:
public class PluviometroDeserializer implements JsonDeserializer<List<Pluviometro>> {
@Override
public List<Pluviometro> deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
final List<Pluviometro> result = new ArrayList<>();
final JsonObject jsonObject = json.getAsJsonObject();
final JsonElement cemaden = jsonObject.get("cemaden");
final JsonArray pluvs = cemaden.getAsJsonArray();
final int pluvsSize = pluvs.size();
for (int i = 0; i < pluvsSize; i++) {
final JsonObject element = pluvs.get(i).getAsJsonObject();
final Pluviometro pluv = new Pluviometro();
pluv.setCodestacao(element.get("codestacao").getAsString());;
pluv.setLatitude(element.get("latitude").getAsDouble());
pluv.setLongitude(element.get("longitude").getAsDouble());
// demais atributos
result.add(pluv);
}
return result;
}
}
That is, first we retrieve the object cemaden
, which is a JsonObject
. Since we know there is an array of rain gauges in it, we can retrieve a JsonArray
. After that, just recover each element (which is the JSON
representation of the object Pluviometro
) and retrieve its attributes.
In this way, when you deserialize, you will directly get the list of rain gauges, doing something like this:
final String jsonResponse = sendGet("http://150.163.255.240/CEMADEN/resources/parceiros/GO/1");
final Type type = new TypeToken<List<Pluviometro>>() {}.getType();
final Gson gson = new GsonBuilder().registerTypeAdapter(type, new PluviometroDeserializer()).create();
final List<Pluviometro> pluviometros = gson.fromJson(jsonResponse, type);;
for (final Pluviometro pluviometro : pluviometros) {
System.out.println("codestacao: " + pluviometro.getCodestacao());
System.out.println("latitude: " + pluviometro.getLatitude());
System.out.println("longitude: " + pluviometro.getLongitude());
// demais atributos
}
This will also generate something like the previous example:
codestacao: 520310401A
latitude: -16.196
longitude: -52.546
So, use the approach that best fits your context.
Note : I'm using the 2.3.1
version in the examples, if you get any errors out there, check the version of the library you're using.
EDITION : including solution for date format error
The date in the return is coming this way: 2015-05-05 11:00:00.0
. To build an instance of Gson
use this pattern: yyyy-MM-dd HH:mm:ss
. An example would look like this:
final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
I noticed that in the return milliseconds are always zeroed , but if you want them too, you can default this here: yyyy-MM-dd HH:mm:ss.S
.