This project will create and delete an entity record. I have chosen JPA for datastore in app engine. You can also look JDO for this purpose. But my choice to go for JPA is due to Sun standardization on it.
I am using App Engine SDK version 1.2.18
Project name: engineplay
URL: http://engineplay1.appspot.com
Project structure:
UserPrefs.java: The entity class
package com.engineplay.datastore.pojos; import javax.persistence.Basic; import javax.persistence.Entity; import javax.persistence.EntityManager; import javax.persistence.Id; import com.engineplay.datastore.EMFService; import com.google.appengine.api.users.User; @Entity (name = "UserPrefs" ) public class UserPrefs { @Id private String userId; private int donuts; @Basic private User user; public UserPrefs(String userId) { this .userId = userId; } /* TODO create getter and setters for above properties yourself */ public static UserPrefs getPrefsForUser(User user) { UserPrefs userPrefs = null ; EntityManager em = EMFService.get().createEntityManager(); try { if (em.find(UserPrefs. class , user.getEmail()) == null ) { userPrefs = new UserPrefs(user.getEmail()); userPrefs.setUser(user); } else { userPrefs = em.find(UserPrefs. class , user.getEmail()); } } finally { em.close(); } return userPrefs; } public void save() { EntityManager em = EMFService.get().createEntityManager(); try { em.persist( this ); } finally { em.close(); } } public void remove() { EntityManager em = EMFService.get().createEntityManager(); try { UserPrefs userPrefs = em.find(UserPrefs. class , user.getEmail()); em.remove(userPrefs); } finally { em.close(); } } } |
EMFService.java: The class to create EntityManagerFactory instance.
package com.engineplay.datastore; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class EMFService { private static final EntityManagerFactory emfInstance = Persistence .createEntityManagerFactory( "transactions-optional" ); private EMFService() { } public static EntityManagerFactory get() { return emfInstance; } } |
LoginServlet.java
package com.engineplay.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.engineplay.datastore.pojos.UserPrefs; import com.google.appengine.api.users.User; import com.google.appengine.api.users.UserService; import com.google.appengine.api.users.UserServiceFactory; public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); String navBar, form = null ; int donuts = 0 ; if (user == null ) { navBar = "<p>Welcome! <a href=\"" + userService.createLoginURL( "/" ) + "\">Sign in or register</a> to customize.</p>" ; form = "" ; } else { UserPrefs userPrefs = UserPrefs.getPrefsForUser(user); if (userPrefs != null ) { donuts = userPrefs.getDonuts(); } navBar = "<p>Welcome, " + user.getEmail() + "! You can <a href=\"" + userService.createLogoutURL( "/" ) + "\">sign out</a>.</p>" ; form = "<form action=\"/donuts\" method=\"post\">" + "<label for=\"donuts\">" + "Need more donuts?:" + "</label>" + "<input name=\"donuts\" id=\"donuts\" type=\"text\" size=\"4\" />" + " <input name=\"olddonuts\" type=\"hidden\" value=\"" + donuts + "\" /> " + " <input name=\"userId\" type=\"hidden\" value=\"" +user.getEmail()+ "\" /> " + " <input type=\"submit\" value=\" ADD \" /><br><input type=\"submit\" name =\"deleteBtn\" value=\" DELETE ME! \" />" + "</form>" ; } resp.setContentType( "text/html" ); PrintWriter out = resp.getWriter(); out.print( "<html><head><title>Engine Play - Donuts</title</head><body>" ); out.println(navBar); if (donuts != 0 ) out.println( "<p>Donuts you have: " + donuts + "</p>" ); else out.println( "<p> No donuts you have :( </p>" ); out.println(form); out.print( "</body></html>" ); } } |
DonutsServlet.java
package com.engineplay.servlet; import java.io.IOException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.engineplay.datastore.pojos.UserPrefs; import com.google.appengine.api.users.User; import com.google.appengine.api.users.UserService; import com.google.appengine.api.users.UserServiceFactory; public class DonutsServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); UserPrefs userPrefs = UserPrefs.getPrefsForUser(user); try { String deleteOpt = req.getParameter( "deleteBtn" ); if (deleteOpt == null ){ int donuts = new Integer(req.getParameter( "donuts" )).intValue(); int oldDonuts = new Integer(req.getParameter( "olddonuts" )).intValue(); userPrefs.setDonuts(donuts + oldDonuts); userPrefs.save(); } else { String userId = req.getParameter( "userId" ); userPrefs.setUserId(userId); userPrefs.remove(); } } catch (Exception e) { e.printStackTrace(); } resp.sendRedirect( "/Login" ); } } |
persistence.xml: Configuration file required for JPA
<? xml version = "1.0" encoding = "UTF-8" ?> < persistence xmlns = "http://java.sun.com/xml/ns/persistence" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version = "1.0" > < persistence-unit name = "transactions-optional" > < provider > org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider </ provider > < properties > < property name = "datanucleus.NontransactionalRead" value = "true" /> < property name = "datanucleus.NontransactionalWrite" value = "true" /> < property name = "datanucleus.ConnectionURL" value = "appengine" /> </ properties > </ persistence-unit > </ persistence > |
web.xml
<? xml version = "1.0" encoding = "utf-8" ?> <! DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> < web-app xmlns = "http://java.sun.com/xml/ns/javaee" version = "2.5" > < servlet > < servlet-name >LoginServlet</ servlet-name > < servlet-class >com.engineplay.servlet.LoginServlet</ servlet-class > </ servlet > < servlet > < servlet-name >DonutsServlet</ servlet-name > < servlet-class >com.engineplay.servlet.DonutsServlet</ servlet-class > </ servlet > < servlet-mapping > < servlet-name >LoginServlet</ servlet-name > < url-pattern >/Login</ url-pattern > </ servlet-mapping > < servlet-mapping > < servlet-name >DonutsServlet</ servlet-name > < url-pattern >/donuts</ url-pattern > </ servlet-mapping > < welcome-file-list > < welcome-file >Login</ welcome-file > </ welcome-file-list > </ web-app > |
Access the project here: http://engineplay1.appspot.com
You can access the code from Github as well.
Tahir,
Nice tutorial. I started out with app engine using the JPA/JDO but then found the low level API to be just as easy. I then disabled the JDO/JPA which allows the project to deploy faster. Have you found a significant advantage of using the JDO/JPA over the low level API?
Thanks Robert.
Its my first program to learn datastore in app engine. I will read about working with low level API and will discuss with you.
I may be tweeting my own horn here, but if you are using the low-level API for real you should give a look to this:
http://code.google.com/p/simpleds/
Great article. I was thinking to explore the app engine. Found a good place to start … Thanks.
Coloma;
I just take a look on the page. Sounds interesting if its easy to use over JPA and JDO. As JPA and SimpleDS both are new for me so learning core JPA will be better investment for me.
Thanks for your comments.
@Robert Lancer:
There is a significat adventage of using JPA over the low level api – you can move your application from Google and deploy it somewhere else, and to do that you only have mappings (probably) – you don’t have to change the code. Using low level api you depends on google – to move your application somewhere else you have to change a bunch of code.
Best regards
Marek
good article, Tahir.
Thanks Veera.
Thanks for your pgm
This is my 1st pgm to run with JPA.
but i didnot know how the html file should be can any one help me.
Nice tutorial!
Visit here if you want to see example usage of Blobstore API on Google App Engine. It shows file uploading via JSP.
http://superdeporter.wordpress.com
Thanks.
Thanks Its nice content on app engine. I am also using google app engine.
Thanks
Jitendra
http://www.javaprogrammings.info
How Did you package and deploy the project ?