Hide
Java

Storing Data in Datastore

In this section, you'll extend the simple application created earlier by adding the ability to post greetings and display previously posted greetings. You'll add a new servlet that handles the form submission and save the data.

The database we are using is Google Cloud Datastore, a scalable, highly reliable data storage service that's easy to use from App Engine. Unlike a relational database, the Datastore is a schemaless object store, with an index-based query engine and transactional capabilities.

This tutorial uses the Objectify library, a Java data modeling library for the Datastore. There are several alternative APIs you can use: a simple low-level API, implementations of the Java Data Objects (JDO) and Java Persistence API (JPA) interfaces, or the Slim3 library.

This is what the app will look like after you add the message submission form:

Hello_UI

You'll make these changes to your existing application:

  • Set up Objectify, and create data model classes for the guestbook.
  • Edit the JSP page to allow users to post greetings to the datastore, and to display all the greetings currently stored.
  • Create a new servlet named SignGuestbookServlet that handles the form submission.
  • Add entries in web.xml so requests can be routed to the new servlet.

Setting up Objectify

To use the Objectify library, you must declare the dependency in the pom.xml file, so Maven can install it. In the application root directory (guestbook/), edit pom.xml, locate the <dependencies> section, then add the following:

<dependency>
    <groupId>com.googlecode.objectify</groupId>
    <artifactId>objectify</artifactId>
    <version>4.0b1</version>
</dependency>

Maven will install the library the next time you run a target that needs it (such as the development server).

In order to use Objectify in a JSP, we need a helper class that registers the model classes in the JSP servlet context. In guestbook/src/main/java/com/example/guestbook/, create a file named OfyHelper.java with the following contents:

This file refers to the Greeting and Guestbook model classes that you'll create in the next section.

Finally, in guestbook/src/main/webapp/WEB-INF/, edit web.xml, and add the following lines inside <web-app> to set up the JSP helper:

Creating the data model classes

With Objectify, you create classes whose instances will represent datastore entities in your code. Objectify does the work of translating these Java objects to datastore entities.

Create a Greeting class to represent a message posted by a user. In guestbook/src/main/java/com/example/guestbook/, create a file named Greeting.java with the following contents:

We also need a Guestbook class to represent an entire guestbook. While this example doesn't explicitly create a Guestbook object in the datastore, it uses this class as part of the datastore key for the Greeting objects. This demonstrates how you might define keys so that all of the greetings in a guestbook could be updated in a single datastore transaction.

Create a file named Guestbook.java with the following contents:

Adding the greetings and the form to the JSP template

In guestbook/src/main/webapp, edit guestbook.jsp. Add the following lines to the imports at the top:

Just above the line <form action="/guestbook.jsp" method="get">, add the following code:

When the user loads the page, the template performs a datastore query for all Greeting entities that use the same Guestbook in their key. The query is sorted by date in reverse chronological order ("-date"), and results are limited to the five most recent greetings. The rest of the template displays the results as HTML, and also renders the form that the user can use to post a new greeting.

See Datastore Queries to learn more about queries.

Creating the form handling servlet

The web form sends an HTTP POST request to the /sign URL. Let's create a servlet to handle these requests.

In guestbook/src/main/java/com/example/guestbook, create a file named SignGuestbookServlet.java, and give it the following contents:

This servlet is the POST handler for the greetings posted by users. It takes the the greeting (content) from the incoming request and stores it in Datastore as a Greeting entity. Its properties include the content of the post, the date the post was created, and, if the user is signed in, the author's ID and email address. For more information about entities in App Engine, see Entities, Properties, and Keys.

Finally, in guestbook/src/main/webapp/WEB-INF/, edit web.xml and ensure the new servlets have URLs mapped. The final version should look like this:

Testing the app

Restart the development server to build and run the app:

mvn appengine:devserver

Visit the app in a browser:

localhost:8080

Try posting a greeting. Also try posting a greeting while signed in, and while not signed in.

Creating required indexes

If your app uses the Datastore, when you run your app on the development server, the development server automatically creates any Datastore indexes required to run in production App Engine. These indexes are generated in guestbook/target/guestbook-1.0-SNAPSHOT/WEB-INF/appengine-generated/datastore-indexes-auto.xml. You'll also notice the file local_db.bin at that same location: this is local storage for the development server to persist your app data between development server sessions. The file datastore-indexes-auto.xml is automatically uploaded along with your app. local_db.bin is not uploaded.

For complete information about indexes, see Datastore Indexes.


We now have a working guest book application that authenticates users using Google accounts, lets them submit messages, and displays messages other users have left.

The only thing left to do is upload our application...

Uploading Your Application >>