The answer 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 [
), once you pass as kind to deserialize a list of Pluviometro
, but there is a {
, that is, the beginning of an object.
There are some ways you can do this, I’ll just quote 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 answer the name of the object is cemaden
, To be more readable the object we need to speak the name of 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 from cemaden
and not pluviometros
, if you wish, 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 outcome:
codestacao: 520310401A
latitude: -16.196
longitude: -52.546
The second way is to use a custom deserializer. Starting from his attempt to immediately return a list of rain gauges, we will make the custom deserializer then return a List<Pluviometro>
.
The work here is a little bigger, because we must take the element JSON
and read each property. It should be 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 recover the object cemaden
, which is a JsonObject
. As we know that there is an array of rain gauges, we can recover a JsonArray
. After this, we just recover each element (which is the representation JSON
of the object Pluviometro
) and recover its attributes.
This way, by deserializar, you will already get directly to 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
Then use the approach you consider best in your context.
Observing: I’m using the version 2.3.1
in the examples, if there is an error there, check the version of the library you are using.
EDITION: including solution to date format error
The date on 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 be like this:
final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
I observed that in return the milliseconds are always zeroed, but if you want them too, you can use as default this here: yyyy-MM-dd HH:mm:ss.S
.
@Afonsooliveiraneto if the answer has helped you, consider accepting it. Thank you
– Bruno César