Monday, March 4, 2013

Java MVC Forms With Morphia and MongoDB part 2

Welcome back! We're going to finish our Java Web application. We're going to create two classes and two page layouts.

Go into NetBeans and create a Java class called NameService in a new package called "service". It's going to have a single method called "AddName", which will take the user input and add it to the document collection. It will also retrieve the whole collection and convert it into an ArrayList. The data will be stuffed into a Name object, be converted into JSON, then stored in MongoDB. Morphia will be handling the conversion of the data between the Name class and JSON. We will call the database "mvcmongo1", and (as I said before), call the collection "names". Here are the namespaces we'll need:


import controller.Name;
import java.util.ArrayList;
import com.mongodb.MongoClient;
import java.net.UnknownHostException;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.google.code.morphia.Morphia;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.BasicDBObject;

And here is the body of the NameService class:


    public static ArrayList<Name> AddName(String first, String last)
            throws UnknownHostException {
        MongoClient client = new MongoClient();
        DB db = client.getDB("mvcmongo1");
        DBCollection coll = db.getCollection("names");
        Name name = new Name();
  //      name.firstName = first;
  //      name.lastName = last;
        name.setFirstName(first);
        name.setLastName(last);
        Morphia morphia = new Morphia();
        DBObject jname = morphia.toDBObject(name);
        coll.save(jname);
        DBCursor cursor = coll.find();
        ArrayList<Name> list = new ArrayList<Name>();
        for (DBObject b : cursor) {
            Morphia morphia2 = new Morphia().map(Name.class);
            BasicDBObject basic = (BasicDBObject)b;
            Name name2 = morphia2.fromDBObject(Name.class, basic);
            list.add(name2);
        }
        return list;
    }

The next step is to create the controller. In Java MVC, a controller's name is capitalized, and the last part of the name must be "Controller". The first part of the name gets de-capitalized as the name of the .htm file the browser accesses.  In our case, we'll call our controller MainController, from which the compiler will generate a main.htm. Create a file of the type Spring Framework >> Simple Form Controller called "MainController", and put it in the "controller" package.

Uncomment the body of the constructor. Use the Name class for the CommandClass, and "name" for the command. That binds the Name class to the form, and the string "name" will be cross-referenced in the form. The constructor should now read as:

    public MainController() {
        //Initialize controller properties here or 
        //in the Web Application Context

        setCommandClass (Name.class);
        setCommandName("name");
        setSuccessView("successView");
        setFormView("formView");
    } 

We are using the defaults for the form view and the verification view ("successView"). Now, delete or comment out the doSubmitAction method and uncomment the onSubmit method. Now, change the body of the onSubmit method to


         Name name = (Name) command;
         ModelAndView mv = new ModelAndView(getSuccessView());
         mv.addObject("nameList", nameService.AddName(name.getFirstName(),
                 name.getLastName()));



Now, right-click and select "Fix Imports". You might need to change some values. The resulting list should contain


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

We're not quite done with the controller. The next step to to put the following at the head of the body of this class:


    private NameService nameService;
    
    public void setNameService(NameService nameService) {
        this.nameService = nameService;
    }

Fix the imports again and save the file. This code creates the nameService object for the onSubmit method. The next step is to configure the website. To do this, add the following bean to applicationContext.xml in the Web Pages\WEB-INF folder. Place it right under the "Beans" header node...

<bean name="nameService" class="service.NameService" />

Refer to that bean in dispatcher-servlet.xml right under the existing bean as follows:

<bean class="controller.MainController" p:nameService-ref="nameService"/>

The last thing to do is create the views in the Web Pages\WEB-INF\jsp folder. Right-click on that folder and select New >> JSP, then call the view "formView". Change the title of the page and the body of the <H1> tag to "Enter Your Name".  Now, under the <H1> tag, place the following:


<spring:nestedPath path="name">
        <form action="" method="post">
            <p>First Name:
            <spring:bind path="firstName">
                <input type="text" name="firstName">
            </spring:bind></p> 
          
            <p>Last Name:
            <spring:bind path="lastName">           
                <input type="text" name="lastName">
            </spring:bind></p>
        
            <p><input type="submit" value="OK"></p>
        </form>
</spring:nestedpath>

The nestedPath path is the same "name" as the "name" that is the command name in the controller. Each <spring:bind> binds that text field to a member in the Name class. Now for last step, the "success" view. Create another JSP file, this time with the name "successView". Change the title and the <H1> body to "Name List". Now, here is the where the JSTL comes in. At the line after the <H1> tag, place the following:


         <c:forEach var="name" items="${nameList}">
            <c:out default="nada" value="${name.firstName}"></c:out>&nbsp;
            <c:out default="nada" value="${name.lastName}"></c:out><br />
         </c:forEach>

The nameList object was created by the controller and sent to this view by its call to the addObject method. This code loops through the ArrayList created by the AddName method and displays the element's contents.

The last step is to right-click on the project's root node and select Properties. Click on "Run" on the left side of the Properties window, and type "main.htm" in the relative URL textbox. Save the changes, then run the application. If all goes well, you should see a form with two textboxes. Every name you have submitted should be in a list on the submission page.  You might need to add the following to the top of the successView file:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

That concludes the tutorial.





No comments:

Post a Comment