AppEngine - java datastore + objectify
Appengine and datastore is a great cloud provider and database to try out on new projects. It supports Java, Python and Go and has a great free layer.
This is a tutorial about how to setup the objectify framework in a java google AppEngine project in order to access datastore in a Java + gradle project.
An entity representing a Comment without relationships will be created.
Add dependencies
in build.gradle edit and add the dependencies:
compile group: 'com.googlecode.objectify', name: 'objectify', version: '5.1.13'
compile 'com.google.appengine:appengine:+'
compile group: 'com.google.appengine', name: 'appengine-api-1.0-sdk', version: '1.9.42'
Create a mapped entity
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;
@Entity
public class Comment {
@Id
private Long id;
private String author;
private String text;
private String postID;
@Index
private Date date;
public Comment() {
}
public Comment(String author, String text, String postID) {
this.author = author;
this.text = text;
this.postID = postID;
this.date = new Date();
}
public Long getId() {
return id;
}
public String getAuthor() {
return author;
}
public String getText() {
return text;
}
public String getPostID() {
return postID;
}
public Date getDate() {
return date;
}
}
Create a OfyService, and register the entities once
For this, I used an static block to register only once the class.
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
public class OfyService {
static {
ObjectifyService.register(Comment.class);
}
public static Objectify ofy(){
return ObjectifyService.ofy();
}
}
Add the Objectify Filter to web.xml
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Create a Servlet
In this servlet, I will read the JSON content, parse it and create the entity from the parameters.
public class CommentServlet extends HttpServlet {
private static final Logger log = Logger.getLogger(CommentServlet.class.getName());
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
log.info("CommentServlet.doGet");
String postID = req.getParameter("postID");
log.info("CommentServlet.postID=" + postID);
Util.addCorsHeader(resp);
List<Comment> comments;
if (postID != null && !postID.equals("")) {
comments = OfyService.ofy().load().type(Comment.class).filter("postID", postID).order("-date").list();
} else {
comments = OfyService.ofy().load().type(Comment.class).order("-date").list();
}
resp.setContentType("application/json");
PrintWriter writer = resp.getWriter();
Gson gson = new Gson();
writer.write(gson.toJson(comments));
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
log.info("CommentServlet.doPost");
String jsonPost = Util.readInputText(req);
Map result = new Gson().fromJson(jsonPost, Map.class);
String author = (String) result.get("author");
String text = (String) result.get("text");
String postID = (String) result.get("postID");
Comment comment = new Comment(author, text, postID);
OfyService.ofy().save().entity(comment).now();
Util.responseOkJSON(resp);
}
@Override
public void doOptions(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
log.info("CommentServlet.doOptions");
String origin = req.getHeader("Origin");
log.info("Origin:" + origin);
Util.addCorsHeader(resp);
}
}
Map the servlet
<servlet>
<servlet-name>comment</servlet-name>
<servlet-class>mussatto.servlet.CommentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>comment</servlet-name>
<url-pattern>/comment</url-pattern>
</servlet-mapping>
The test code
public class CommentServletIntegrationTest {
@Test
public void commentServletTest() {
Map<String, Object> params = new HashMap<>();
params.put("author", "Noel Rosa");
params.put("text", "com que roupa eu vou, pro samba que voce me convidou?");
params.put("postID", "123456");
JSONPost post = new JSONPost("http://localhost:8080/comment", params);
try {
post.doPost();
} catch (IOException e) {
System.out.println(e);
fail();
}
System.out.println(post.getResponseCode());
System.out.println(post.getResponse());
}
}