Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Start a New MVC Spec Project With MongoDB

DZone's Guide to

Start a New MVC Spec Project With MongoDB

Time to walk on the Java EE, er... EE4J side of things with the Ozark project. See how it provides an action-based solution to MVC projects.

· Java Zone ·
Free Resource

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

The MVC, from Wikipedia, is a software architectural pattern that divides a given application into three interconnected parts. It is done to separate internal representations of information from the ways information is presented to, and accepted from, the user.

The MVC design pattern decouples these significant components, allowing for efficient code reuse and parallel development. MVC web frameworks can be categorized either as action-based or component-based. For decades, the Java Community was waiting for a specification that is action-based. Of course, the Java EE world already has Java Server Faces as a component-based. Finally, the action-based MVC is coming with Ozark.

The project's spec leaders are Ivar Grimstad and Christian Kaltenpoth. As most JSRs are, it's an open source project, and they're moving the code to Eclipse Foundation under the EE4J umbrella.

Minimum Requirements

  • Java 8
  • Any Java EE 8 server such as Glassfish-5.0, the Java EE 8 reference implementation
  • Apache Maven 3.3.9 or higher
  • MongoDB 3.4 or higher running

The MongoDB database must be running while the server is up, so you can either download and install it manually or use a Docker image and then run the command:

docker run -d --name mongodb-instance -p 27017:27017 mongodb


Modeling

The next step is to define the user model. To make this all smoother, this user just has a country, state, name, age, JUG, and description as information. So, two classes:

  • The Person class: name, age, JUG, and any description
  • The Address class: country and state

As with any simple register page, the user information comes through in page form, so the MVC frameworks comes with the FormParam annotation. This way, the developer can connect the form with any input field once the annotation has the exact name from the name input tag.

The MongoDB integration with the model is easy as well; JNoSQL has annotations that look like the JPA, so the developer defines the Entity, the column, and the id using the Entity, column, and Id annotations, respectively.

One difference with MongoDB is that we can store all the Address class information as a field instead of making a relationship as we usually do with SQL technology. So, we'll use the Embeddable annotation to define that field will be shipped as a field, the subdocument approach.

@Entity
public class Person {

    @FormParam("id")
    @Id
    @Convert(ObjectIdConverter.class)
    private String id;

    @FormParam("name")
    @Column
    private String name;

    @FormParam("age")
    @Column
    private int age;

    @BeanParam
    @Column
    private Address address;

    @FormParam("jugs")
    @Column
    private String jugs;

    @FormParam("description")
    @Column
    private String description;


//getters

}

@Embeddable
public class Address {

    @FormParam("country")
    @Column
    private String country;

    @FormParam("state")
    @Column
    private String state;

//getters
}


The Repository

The repository is a DDD pattern that is a mediator between the domain and data mapping layers using a collection-like interface for accessing domain objects.

To make this connection, we need two steps.

The first one is making a JNoSQL connection available at the CDI container. Basically, we create a method that produces DocumentCollectionManager.

@ApplicationScoped
public class DocumentCollectionProducer {


    private static final String DOCUMENT_COLLECTION = "people";

    @Produces
    @ApplicationScoped
    public DocumentCollectionManager getDocumentCollectionManager() {
        DocumentConfiguration<?> configuration = new MongoDBDocumentConfiguration();
        Settings settings = Settings.builder().put("mongodb-server-host-1", "localhost:27017").build();
        DocumentCollectionManagerFactory managerFactory = configuration.get(settings);
        return managerFactory.get(DOCUMENT_COLLECTION);
    }
}


The next and last step is to create a Person repository. What we need is an interface that extends Repository. That is it, JNoSQL will handle the implementation for you. Here is the method with a query whose the whole point is to let the Java developer create any method using the JNoSQL convention. Then, the framework will implement that.

public interface PersonRepository extends Repository<Person, String> {

    List<Person> findAll();
}


The Controller

The controller is the bridge to connect the view, the JSP page, and the model. 

Models is a map of the name to model instances used by ViewEngine to process a view.

Viewable is an abstraction that encapsulates information about a view.

The other points are clear enough. Use the GET annotation to define access and POST to define the PATH that establishes an URL path.

@Controller
@Path("mvc")
public class PersonController {

    private static final Supplier<WebApplicationException> NOT_FOUND_EXCEPTION = () -> new WebApplicationException(NOT_FOUND);

    @Inject
    private Models models;

    @Inject
    @Database(DatabaseType.DOCUMENT)
    private PersonRepository repository;

    @GET
    @Path("new")
    public Viewable newElement() {
        return new Viewable("insert.jsp");
    }

    @GET
    @Path("show")
    @View("list.jsp")
    public void list() {
        this.models.put("list", repository.findAll());
    }

    @POST
    @Path("add")
    public String add(@BeanParam Person person) {
        repository.save(person);
        return "redirect:mvc/show";
    }

    @POST
    @Path("update")
    public String update(@BeanParam Person person) {
        repository.save(person);
        return "redirect:mvc/show";
    }

    @GET
    @Path("update/{id}")
    public Viewable update(@PathParam("id") String id) {

        Optional<Person> person = repository.findById(id);
        this.models.put("person", person.orElseThrow(NOT_FOUND_EXCEPTION));
        return new Viewable("change.jsp", models);
    }

    @GET
    @Path("remove/{id}")
    public String delete(@PathParam("id") String id) {
        repository.deleteById(id);
        return "redirect:mvc/show";
    }
}


The View

The view/visualization layer will work with the old, but gold JSP pages from the Java world.

The insert page:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert</title>
</head>
<body>
<div align="center">
    <form action="add" method="post">

        <fieldset style="width: 400px">
            <legend>Data</legend>

            Name: <input type="text" name="name"/><br/><br/>
            Age: <input type="number" name="age"/><br/> <br/>
            Country: <input type="text" name="country"/><br/><br/>
            State: <input type="text" name="state"/><br/><br/>
            JUGS:<input type="radio" name="jugs" value="SouJava"/>SouJava
            <input type="radio" name="jugs" value="RioJug"/>RioJug
            <input type="radio" name="jugs" value="SouJava Campinas"/>SouJava Campinas<br/><br/>

            <textarea rows="10" cols="30" name="description">Description</textarea>
            <br/><br/>

            <input type="submit" value="Insert"/>

        </fieldset>
    </form>
</div>
</body>
</html>


The edit page:

<%@page contentType="text/html" language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Update data</title>
</head>
<body>
<div align="center">
    <form action="../update" method="post">
        <fieldset style="width: 400px">
            <legend>Change of Data</legend>

            <input type="text" name="id" value="${person.id}" hidden="true">
            <input type="text" name="jugs" value="${person.jugs}" hidden="true"><br/><br/>
            Name:<input type="text" name="name" value="${person.name }"><br/><br/>
            Age: <input type="number" name="age" value="${person.age }"/><br/> <br/>
            Country:<input type="text" name="country" value="${person.address.country}"><br/><br/>
            State:<input type="text" name="state" value="${person.address.state}"><br/><br/>

            <textarea rows="10" cols="30" name="description">${person.description}</textarea>
            <br/><br/>

            <input type="submit" value="Update">
        </fieldset>
    </form>
</div>
</body>
</html>


The list page:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Show</title>
</head>
<body>

<h1 align="center">Data Listing</h1>

<a href="new">Add</a>

<table align="center" border="4">
    <tr bgcolor="gray">
        <th>Name</th>
        <th>Age</th>
        <th>Country</th>
        <th>State</th>
        <th>JUGS</th>
        <th>Description</th>
        <th>Edit</th>
        <th>Delete</th>
    </tr>
    <c:forEach items="${list}" var="person">
        <tr>
            <td>${person.name}</td>
            <td>${person.age}</td>
            <td>${person.address.country}</td>
            <td>${person.address.state}</td>
            <td>${person.jugs}</td>
            <td>
                <textarea rows="10" cols="60" name="description" disabled="disabled"> ${person.description} </textarea>
            </td>
            <td><a href="update/${person.id}">Edit</a></td>
            <td><a href="remove/${person.id}">Delete</a></td>
        </tr>
    </c:forEach>
</table>
</body>
</html>



That is it! This sample code now has the shape of the new spec coming with MVC 1.0. That is an excellent opportunity to give feedback and check how everything is. One crucial point is that is just the first version.

References

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

Topics:
mvc ,ee4j ,mongodb ,java ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}