Solution to Challenge: Gson

I’m trying to make to code and compact as possible basicly you need to construct a class and matches the data you recieve from flickr and gson can automaticly fit in those data into your class and the parsing part of
the code can be skipped
FlickrFetchr.java

import android.net.Uri;
import android.util.Log;

import com.google.gson.Gson;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class FlickrFetchr {

    private static final String TAG = "FlickrFetchr";
    private static final String API_KEY = "YOU_ACTUAL_KEY_HERE";
    public byte[] getUrlBytes(String urlSpec) throws IOException {
        URL url = new URL(urlSpec);
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            InputStream in = connection.getInputStream();
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                throw new IOException(connection.getResponseMessage() +
                        ": with " +
                        urlSpec);
            }
            int bytesRead = 0;
            byte[] buffer = new byte[1024];
            while ((bytesRead = in.read(buffer)) > 0) {
                out.write(buffer, 0, bytesRead);
            }
            out.close();
            return out.toByteArray();
        } finally {
            connection.disconnect();
        }
    }
    public String getUrlString(String urlSpec) throws IOException {
        return new String(getUrlBytes(urlSpec));
    }

    public List<GalleryItem> fetchItems() {
        List<GalleryItem> items = new ArrayList<>();
        try {
            String url = Uri.parse("https://api.flickr.com/services/rest/")
                    .buildUpon()
                    .appendQueryParameter("method", "flickr.photos.getRecent")
                    .appendQueryParameter("api_key", API_KEY)
                    .appendQueryParameter("format", "json")
                    .appendQueryParameter("nojsoncallback", "1")
                    .appendQueryParameter("extras", "url_s")
                    .build().toString();
            String jsonString = getUrlString(url);
            Log.i(TAG, "Received JSON: " + jsonString);
            Gson gson           = new Gson();
            GalleryPage pge = gson.fromJson(jsonString,GalleryPage.class);
            items                   = pge.getGalleryItemList();
           
        } catch (IOException ioe) {
            Log.e(TAG, "Failed to fetch items", ioe);
        }
        return items;
    }

   
}

Two new class created under GalleryPage.java

import com.google.gson.annotations.SerializedName;
import java.util.List;

public class GalleryPage {
    PhotoResults photos;
    String stat;
    public List<GalleryItem> getGalleryItemList() {
        return photos.getPhotoList();
    }
}

 class PhotoResults {
    int page;
    int pages;
    int perpage;
    int total;
    @SerializedName("photo")
    List<GalleryItem> photoList;
    List<GalleryItem> getPhotoList() {
        return photoList;
    }
}

GalleryItem.java

import com.google.gson.annotations.SerializedName;

public class GalleryItem {
  @SerializedName("title")
  private String mTitle;
  @SerializedName("id")
  private String mId;
  @SerializedName("url_s")
  private String mUrl;

  public String getTitle()              { return mTitle; }

  public void setTitle(String title) { mTitle = title; }

  public String getId()                  { return mId;    }

  public void setId(String id)       {  mId = id;       }

  public String getUrl()               { return mUrl;   }

  public void setUrl(String url)   { mUrl = url;     }
}

I changed some of the name to my own preference but the general structure should be the same as the book

1 Like

Yes, unfortunately it seems this is the conventional way of doing this thing with Gson. The way the book described it, I originally expected the code to be shortened, not lengthened, when implemented with Gson. With the JSON that needs parsing for this particular example, it is simpler and easier to just use the convenience methods as done in the text. Thanks for sharing!

Simple but effective solution