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.
Join the DZone community and get the full member experience.
Join For FreeThe 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
Opinions expressed by DZone contributors are their own.
Trending
-
HashMap Performance Improvements in Java 8
-
Creating Scalable OpenAI GPT Applications in Java
-
Zero Trust Network for Microservices With Istio
-
How To Integrate Microsoft Team With Cypress Cloud
Comments