Ch 25 Challenge Gson solution

See Gson — Getting Started with Java-JSON Serialization & Deserialization for a description of how to use Gson.

  1. File/Project Structure add a Gson dependency com.google.code.gson:gson:2.8.2
  2. modify class GalleyItems variables to

Note: I used Json variable photoJsonArray because it was already a json array and I didn’t see a way to check if the url_s was empty ( so this needs to be done somewhere).

public class GalleyItem {
@SerializedName(“title”)
@Expose()
private String mCaption;
@SerializedName(“id”)
@Expose()
private String mId;
@SerializedName(“url_s”)
@Expose()
private String mUrl;

// All other code is the same
}

  1. change FlickrFetchr parseItems() function to

private void parseItems(List items, JSONObject jsonBody)
throws IOException , JSONException {

    Gson gson = new Gson();
    Type galleyItemType = new TypeToken<ArrayList<GalleyItem>>(){}.getType();

    JSONObject photosJsonObject = jsonBody.getJSONObject("photos");
    JSONArray photosJsonArray = photosJsonObject.getJSONArray("photo");
    String jsonPhotosString = photosJsonArray.toString();

    List<GalleyItem> galleyItemList =  gson.fromJson(jsonPhotosString,galleyItemType);
    items.addAll(galleyItemList);


}
2 Likes

Can you explain why we need @SerializedName(“title”) and @Expose()?

The @ character is a annotation , so the @serializedname(“title”) tells Gson the json field “title” will match to the class field mCaption (which must come after the annotation). The @expose annotation is actually not needed here. The @expose if not written defaults to @Expose (serialize = true, deserialize = true), this means that the class field will alway be used when json in converted to this class field and is always used when converting this java class to its json representative. So you should be able to remove the @expose but you need the @serializedname.

2 Likes

Correction. The @expose annotation “This annotation has no effect unless you build Gson with a GsonBuilder and invoke GsonBuilder.excludeFieldsWithoutExposeAnnotation() method.”

https://static.javadoc.io/com.google.code.gson/gson/2.6.2/com/google/gson/annotations/Expose.html

You can use the @JsonRequired annotation, write your own deserializer. If the url_s absent in the JSON answer, you will get an exception, so you can catch it and continue you loop.

Here is an example on stackoverflow

You can avoid this lines
JSONObject photosJsonObject = jsonBody.getJSONObject("photos");
JSONArray photosJsonArray = photosJsonObject.getJSONArray("photo");
String jsonPhotosString = photosJsonArray.toString();
by creating a List<?> photo in you class if you wish. As for me it was useful for understanding the GSON library =)