The article represents key aspects of integrating your Spring MVC web application with Google NoSQL Datastore while working on Google App Engine cloud computing platform. Additionally, it presents code samples for you to get started in a quick manner.
You may access the sample application talked about in this article on this page, Welcome to GAE World!
Following has been discussed:
- High-level architecture & design
- Setup
- NoSQL Data Model (NoSQL data entity vis-a-vis Google Datastore)
- Implementation including code samples such as following:
- Controller (HelloController)
- JSP (hello.jsp)
- DAOs (GoogleDSCommentDAO)
High-level Architecture & Design
Following are key technologies used for the implementation discussed in this article:
- Spring MVC
- Google Datastore (NoSQL Database)
- Jetty (Web Server)
- Bootstrap (UI) for rapid good looking UI widgets
- Google App Engine as cloud computing platform
The web application is based on MVC architecture pattern and is developed using Spring component model. You would see key concepts of Spring (Annotations based dependency injection) being used in the code samples listed below.
Setup
For you to be able to get up and running with using Google Datastore with Spring MVC, we recommend you to go through our previous articles such as following:
Google NoSQL Datastore & Related Implementation
The key to implementing Google NoSQL datastore is understanding of concepts around Google NoSQL such as Entity, Key, Kind, Attribute etc. Some of these concepts are described below in light of sample implementation shown in this article:
NoSQL Data Entity (Comment)
Take a look at following pages to get an overview on Google Datastore and related key concepts.
“Comment” is created as an entity in NoSQL Datastore. It has attributes (analogous to columns in RDBMS) such as email, text and date which is stored in Google NoSQL datastore.
CommentDAO.java
Pay attention to the fact that interface does not consist of Google DS specific objects (such as Key, Entity etc) in the method signature. This is just to make sure that interface definitions are implementation agnostic and could be used for both RDBMS and NoSQL database. For this very reason, “Comment” domain object is conceptualized such that it could be passed in between controller and model objects.
public interface CommentDAO {
long save( Comment comment );
List getAll( int count );
}
GoogleDSCommentDAO.java
This class implements following two methods of the interface, CommentDAO.
- save( Comment comment) : Saves the comment entity in the Google NoSQL datastore
- getAll( int count): Get “count” number of comments entities from the datastore
import java.util.ArrayList; import java.util.Date; import java.util.List; import org.springframework.stereotype.Component; import com.google.appengine.api.datastore.DatastoreService; import com.google.appengine.api.datastore.DatastoreServiceFactory; import com.google.appengine.api.datastore.Entity; import com.google.appengine.api.datastore.FetchOptions; import com.google.appengine.api.datastore.Key; import com.google.appengine.api.datastore.KeyFactory; import com.google.appengine.api.datastore.Query; @Component public class GoogleDSCommentDAO implements CommentDAO { public static final String EntityKind = "TestComments"; @Override public long save(Comment comment) { Key commentKey = KeyFactory.createKey( EntityKind, comment.getEmail()); Entity commentEntity = new Entity("Comment", commentKey); commentEntity.setProperty("email", comment.getEmail()); commentEntity.setProperty("date", comment.getDate()); commentEntity.setProperty("text", comment.getText()); DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Key key = datastore.put(commentEntity); return key.getId(); } public List getAll( int count ) { DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Query query = new Query("Comment").addSort("date", Query.SortDirection.DESCENDING); List entities = datastore.prepare(query).asList(FetchOptions.Builder.withLimit( count )); List comments = new ArrayList(); if( entities != null && entities.size() > 0 ) { for( Entity entity: entities ) { comments.add( createCommentFromEntity( entity ) ); } } return comments; } private Comment createCommentFromEntity( Entity entity ) { Comment comment = new Comment(); comment.setEmail( (String)entity.getProperty("email") ); comment.setText( (String)entity.getProperty("text") ); comment.setDate( (Date)entity.getProperty("date") ); return comment; } }
Implementation & Code Samples
Following is listed code samples for controller and view.
HelloController.java (Controller)
Method: newComment( ModelMap model )
//Display all the comments along with fields to create new entry in hello.jsp @RequestMapping(value = "/springmvc/helloworld", method = RequestMethod.GET) public ModelAndView newComment( ModelMap model ) { List comments = commentsImpl.getAll( 10 ); return new ModelAndView("hello", "comments", comments ); }
Method: createComment( @RequestParam(“email”) String email, @RequestParam(“comment”) String text )
//Create new entry upon the submission of the form in page, hello.jsp @RequestMapping(value = "/springmvc/createcomments", method = RequestMethod.POST) public ModelAndView createComment( @RequestParam("email") String email, @RequestParam("comment") String text ) { Comment comment = new Comment(); comment.setEmail(email); comment.setText( text ); comment.setDate( new Date() ); Long id = commentsImpl.save( comment ); String message = null; if( id > 0 ) { message = "Data saved in the datastore!"; } else { message = "Data failed to get saved in the datastore!"; } List comments = commentsImpl.getAll( 10 ); ModelAndView model = new ModelAndView("hello"); model.addObject("message", message ); model.addObject("comments", comments ); return model; }
hello.jsp (View)
Following snippets display the key code blocks to display the comments.
<div> <% List<Comment> comments = (List<Comment>) request.getAttribute( "comments" ); if (comments.isEmpty()) { %> <div style="padding:0px 0px 0px 25px"> No comments are found to be entered. </div> <% } else { for (Comment comment : comments) { pageContext.setAttribute("comment", comment.getText()); pageContext.setAttribute("email", comment.getEmail()); pageContext.setAttribute("date", comment.getDate()); %> <div style="padding:0px 0px 0px 25px"> <div> ${comment} </div> <div style="padding-top:10px;font-size:11px"> Posted by: ${email}, Date: ${date} </div> </div> <hr/> <% } } %> </div>
Recommended Books
Download
If you would like to get access to entire code for quick coding, download from this page.
- Agentic Reasoning Design Patterns in AI: Examples - October 18, 2024
- LLMs for Adaptive Learning & Personalized Education - October 8, 2024
- Sparse Mixture of Experts (MoE) Models: Examples - October 6, 2024
I found it very helpful. However the differences are not too understandable for me