Chapter 10. Bringing it Together

At last, it's time to bring everything together. Earlier in Chapter 8, Exploring External Databases, we started our example of writing a Blockbuster games application by creating a new Google App Engine (GAE) project and building up the JDO database. We first defined what our VideoGame table should look like, and then we wrote a handful of convenient wrapper methods which would allow us to retrieve, insert, update, and/or delete VideoGame data from our backend. Then in Chapter 9, Collecting and Storing Data, we looked at various ways in which we could collect data, either by using convenient APIs or by writing scrapers to do the dirty work for us. In our example, a scraper was necessary and so we wrote some code to first clean and structure Blockbuster's game rental page, before finally navigating and parsing the desired data. The last step was simply to reintroduce ourselves to HTTP servlets and look at how we could implement a servlet that, when hit, would scrape and update our database with the latest games.

Now, we'll finish off the application by writing an HTTP servlet that will actually query and return data (as opposed to our earlier example, which simply returned a success or failure message), and, once returned, we'll write some simple XML parsers and list adapters to show you what to do with the data once it's on the mobile side. Then, you'll have a fully functional backend that will periodically scrape and update its own data, a series of HTTP servlets that will allow you to retrieve data independent of the platform, and an Android application that will parse the data and bind it to the UI for the user to see.

Implementing HTTP GET requests

In the last chapter, we briefly went over the difference between a GET and POST request. The next step in our application development is writing a few classes on the GAE server side which will allow us to hit a URL and get back a list of video game objects.

This means we need to override another HTTP servlet which will likely take a parameter that indicates which game platform we're looking for. Intuitively, once we know the platform we're looking for, we recall from earlier that one of our wrapper methods for our JDO database involved querying for all games of a certain platform. Hence, we'll likely need to utilize our JDO wrapper class again.

However, you might also recall that our JDO database returns rows not as strings but as objects, and so we'll need to take the additional step of converting each VideoGame object into some kind of readable, formatted string, whether as XML or JSON. With these initial thoughts and intuitions at hand, let's take a look at how you would implement this new GET request:

public class GetVideoGames extends HttpServlet {

    // HTTP GET REQUEST SINCE WE'RE REQUESTING FOR DATA
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String platform = request.getParameter("type");

        // USE OUR JDO WRAPPER TO QUERY FOR GAMES BY PLATFORM
        List<VideoGame> games = VideoGameJDOWrapper.getGamesByType(platform);

        // WRAP GAMES INTO XML FORMAT
        String ret = GamesToXMLConverter.convertGamesToXML(games);

        // SET THE RESPONSE TYPE TO XML
        response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");

        // WRITE DATA TO RESPONSE
        response.getWriter().write(ret);
    }

}

Everything should look familiar and the logic is fairly simple. The only part that's unclear is near the end when I pass in a list of VideoGame objects and get back a string. As the name of the class suggests, I wrote a simple class which takes VideoGame objects, strips out their fields, and organizes them into well-formatted XML code (again, you could use JSON as well). Let's take a quick look at how I defined my GamesToXMLConverter class:

public class GamesToXMLConverter {

	public static String convertGamesToXML(List<VideoGame> games) {
		String content = "";
		for (VideoGame g : games) {
			// WRAP EACH GAME IN ITS OWN TAG
			content += convertGameToXml(g);
		}
      // WRAP ALL GAME TAGS TOGETHER INTO ROOT AG

		String ret = addTag("games", content);
		return ret;
	}

	/**
	 * METHOD FOR CONVERTING OBJECT TO XML FORMAT
	 * 
	 * @param g
	 *            a video game object
	 * @return
	 */
	public static String convertGameToXml(VideoGame g) {
		String content = "";
		// ADD TAG FOR NAME
		content += addTag("name", g.getName().replaceAll("&", "and"));

		// ADD TAG FOR ID
		content += addTag("id", String.valueOf(g.getId()));
		
		// ADD TAG FOR IMAGE IF NOT NULL
		if (g.getImgUrl() != null) {
			content += addTag("imgUrl", g.getImgUrl().getValue());
		}

		// ADD TAG FOR TYPE
		content += addTag("type", VideoGameConsole.convertIntToString(g.getConsoleType()));

		// WRAP ENTIRE GAME IN <game> TAGS
		String ret = addTag("game", content);
		return ret;
	}

	public static String addTag(String tag, String value) {
		return ("<" + tag + ">" + value + "</" + tag + ">");
	}

}

And voila – nothing too complicated. Really, you can write your XML/JSON converters in any way you'd like – in fact, if you search hard enough, I'm willing to bet there are convenient libraries out there which are designed to do this for you. However, as is the theme of this book, focus more on the concepts and less on my actual code – the idea is you reach into your JDO database and get back a list of objects and from there you simply need to think of a clean way to write those objects into the HttpServletResponse object that is retured.

And again, just like with our previous HTTP servlet, in order for our GAE project to recognize this as a valid servlet, we need to define it as one in the /war/WEB-INF/web.xml file:

<?xml version="1.0" encoding="utf-8"?>


    <servlet>
        <servlet-name>getVideoGames</servlet-name>
        <servlet-class>app.requests.GetVideoGames</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getVideoGames</servlet-name>
        <url-pattern>/getVideoGames</url-pattern>
    </servlet-mapping>

And once we have our name and URL pattern defined, we simply deploy the project and hit the following URL:

http://{your-project-name}.appspot.com/getVideoGames?type={type}

And we're done. For those following along, I invite you to check it out and see if you get a nicely formatted list of data. Otherwise, feel free to check out the following links to see my results:

http://entertainmentapp.appspot.com/getVideoGames?type=Xbox

http://entertainmentapp.appspot.com/getVideoGames?type=Ps3

The following is a screenshot for those reading this on the go:

Implementing HTTP GET requests

And now, let's move it back to the Android side and see how we would both make the request and then handle/parse the result.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.103.219