A comprehensive step by step Java tutorial on how to create Java and MongoDB CRUD web app using Spring Boot, Spring MVC, and Spring Data
Java tutorial: This is a practical step by step tutorial on how to create Java and MongoDB create, read, update, and delete (CRUD) web app using Spring Boot, Spring MVC, and Spring Data. In this tutorial, we are using Gradle based project for compile, build, and run the Java web app. The project will be generated using Spring Initializr online Java project generator. For the development process, we are use Netbeans 8.2 IDE to make development easier and faster.
We will show you how to create the Java web app that can display the list of product, show, create, edit, update and delete it using Spring MVC. The data GET, POST, PUT, and DELETE from MongoDB using Spring Data. We’re using the following tools, framework, and library:
We assume that you have installed JDK 8, Gradle and IDE (Netbeans or Eclipse). Next, we will create a new Spring Boot Gradle project using Spring Initializer. Spring Initializr provides an extensible API to generate quickstart projects, and to inspect the metadata used to generate projects, for instance, to list the available dependencies and versions. Just go to Spring Initializer web-based Spring project generator then fill the required frameworks and libraries.
After filling all fields, click Generate Project. It will automatically download the zipped project. Next, extract the zipped project to your java projects folder. On the project folder root, you will find build.gradle
file for register dependencies, initially it looks like this.
buildscript {
ext {
springBootVersion = '1.5.6.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Next, open the terminal then goes to the newly extracted project folder then type this command.
./gradlew build
It will build and install all Gradle dependencies. Open this Gradle project using Netbeans or Eclipse then open and edit build.gradle
from the root of the project folder. Add this line to dependencies to install additional Twitter Bootstrap front UI/UX.
compile('org.webjars:bootstrap:3.3.7')
On the terminal run again this command.
./gradlew build
To configure Spring Data with MongoDB, simply open and edit src/resources/application.properties
then add these lines of strings.
spring.data.mongodb.database=springmongodb
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
Part of the MVC concept is Model/Entity/Domain. For that, we will create a new Model or Entity class. The entity is a lightweight Java class whose state is typically persisted to a table or collection in a relational or document database. Using IDE like Netbeans 8.2 right-click on the project name in projects panel then choose New then choose Java Class.
Give the class name Product
and the package name com.springmvc.springmongodbweb.models
then click the finish button.
That will create a new file name Product.java
and open in Netbeans main panel. Fill with the codes below that contain Java POJO, Spring Data MongoDB annotation that point to a collection, fields with their types, constructor, and getter/setter methods.
package com.springmvc.springmongodbweb.models;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "products")
public class Product {
@Id
String id;
String prodName;
String prodDesc;
Double prodPrice;
String prodImage;
public Product() {
}
public Product(String prodName, String prodDesc, Double prodPrice, String prodImage) {
this.prodName = prodName;
this.prodDesc = prodDesc;
this.prodPrice = prodPrice;
this.prodImage = prodImage;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getProdName() {
return prodName;
}
public void setProdName(String prodName) {
this.prodName = prodName;
}
public String getProdDesc() {
return prodDesc;
}
public void setProdDesc(String prodDesc) {
this.prodDesc = prodDesc;
}
public Double getProdPrice() {
return prodPrice;
}
public void setProdPrice(Double prodPrice) {
this.prodPrice = prodPrice;
}
public String getProdImage() {
return prodImage;
}
public void setProdImage(String prodImage) {
this.prodImage = prodImage;
}
}
That product class mapping to products collections of MongoDB which has 5 fields. Each field has getter and setter.
Now, we need to create an interface for connecting the Product model and controller. On Netbeans right-click project name on projects left panel then choose new then choose Java Interface.
Give the name of interface ProductRepository
and create new package name com.springmvc.springmongodbweb.repositories
then click Finish.
It will open ProductRepository.java
interface file on the Netbeans main panel after created. Just replace all codes with these codes of ProductRepository that extends Spring Data CrudRepository that return Product and String objects.
package com.springmvc.springmongodbweb.repositories;
import com.springmvc.springmongodbweb.models.Product;
import org.springframework.data.repository.CrudRepository;
public interface ProductRepository extends CrudRepository<Product, String> {
@Override
Product findOne(String id);
@Override
void delete(Product deleted);
}
We only add findOne
and delete
method to the interface because the rest method already handled by CrudRepository
of Spring Data MongoDB.
Now, it’s time for C
terms of MVC that means Controller. To create it on Netbeans just right click on project name from projects left panel then choose new then choose Java Class.
Give the name of controller class ProductController
and create a new package name com.springmvc.springmongodbweb.controllers
then click Finish.
It will open ProductController.java
file on the Netbeans main panel after created. Replace all codes with these codes of the implementation of ProductRepository, Spring Framework model, request, response, params, etc.
package com.springmvc.springmongodbweb.controllers;
import com.springmvc.springmongodbweb.models.Product;
import com.springmvc.springmongodbweb.repositories.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ProductController {
@Autowired
ProductRepository productRepository;
@RequestMapping("/product")
public String product(Model model) {
model.addAttribute("products", productRepository.findAll());
return "product";
}
@RequestMapping("/create")
public String create(Model model) {
return "create";
}
@RequestMapping("/save")
public String save(@RequestParam String prodName, @RequestParam String prodDesc, @RequestParam Double prodPrice, @RequestParam String prodImage) {
Product product = new Product();
product.setProdName(prodName);
product.setProdDesc(prodDesc);
product.setProdPrice(prodPrice);
product.setProdImage(prodImage);
productRepository.save(product);
return "redirect:/show/" + product.getId();
}
@RequestMapping("/show/{id}")
public String show(@PathVariable String id, Model model) {
model.addAttribute("product", productRepository.findOne(id));
return "show";
}
@RequestMapping("/delete")
public String delete(@RequestParam String id) {
Product product = productRepository.findOne(id);
productRepository.delete(product);
return "redirect:/product";
}
@RequestMapping("/edit/{id}")
public String edit(@PathVariable String id, Model model) {
model.addAttribute("product", productRepository.findOne(id));
return "edit";
}
@RequestMapping("/update")
public String update(@RequestParam String id, @RequestParam String prodName, @RequestParam String prodDesc, @RequestParam Double prodPrice, @RequestParam String prodImage) {
Product product = productRepository.findOne(id);
product.setProdName(prodName);
product.setProdDesc(prodDesc);
product.setProdPrice(prodPrice);
product.setProdImage(prodImage);
productRepository.save(product);
return "redirect:/show/" + product.getId();
}
}
On that controller class, we put all CRUD function that interacts between view and model.
Now, it’s the time of V
for the View of MVC pattern. Since we are using Thymeleaf library for view template, so we can create the same layout for all HTML pages. Thymeleaf is a Java XML/XHTML/HTML5 template engine that can work both in web (servlet-based) and non-web environments. It is better suited for serving XHTML/HTML5 at the view layer of MVC-based web applications, but it can process any XML file even in offline environments. To create the layout, first, create a default.html
file on the Resources/templates
folder then add or replace with these lines of codes.
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8"/>
<title>Default title for my pages</title>
<link rel="stylesheet" href="/webjars/bootstrap/3.3.7/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/bootstrap/3.3.7/css/bootstrap-theme.min.css"/>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="/product">Home</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<div class="starter-template" layout:fragment="content"></div>
</div><!-- /.container -->
<script src="/webjars/jquery/1.11.1/jquery.min.js"></script>
<script src="/webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
All CSS and Javascript files put on that file and called once for all pages that use default.html
as layout holder. Also, we call Bootstrap and JQuery on that file. Next, we create a view for Product list with the name product.html
then replace all codes to that file with this.
<!DOCTYPE HTML>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
<title>Product List</title>
</head>
<body>
<div layout:fragment="content" class="row">
<div class="col-xs-8 col-md-8">
<h3>
<a href="/create" class="btn btn-primary"><span class="glyphicon glyphicon-plus-sign"></span> Product</a>
</h3>
<h2>Product List</h2>
<div class="table-responsive">
<table class="table" id="product-table">
<thead>
<tr>
<th>Product Name</th>
<th>Product Desc</th>
<th>Product Price</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${products}">
<td><a th:text="${product.prodName}" th:href="@{'/show/' + ${product.id}}"></a></td>
<td th:text="${product.prodDesc}"></td>
<td th:text="${product.prodPrice}"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Next, create a view for creating a product form with the name create.html
on Resources/templates
folder then replace all codes with this.
<!DOCTYPE HTML>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
<title>Create Product</title>
</head>
<body>
<div layout:fragment="content" class="row">
<div class="col-xs-8 col-md-8">
<h3>
<a href="/product" class="btn btn-lg btn-primary"><span class="glyphicon glyphicon-list"></span> Product</a>
</h3>
<h2>Create Product</h2>
<form action="/save">
<div class="form-group">
<label for="email">Product Name:</label>
<input type="text" class="form-control" name="prodName" />
</div>
<div class="form-group">
<label for="email">Product Description</label>
<textarea class="form-control" name="prodDesc" cols="60" rows="3"></textarea>
</div>
<div class="form-group">
<label for="email">Product Price</label>
<input type="number" class="form-control" name="prodPrice" />
</div>
<div class="form-group">
<label for="email">Product Image URL:</label>
<input type="url" class="form-control" name="prodImage" />
</div>
<button type="submit" class="btn btn-success">Save</button>
</form>
</div>
</div>
</body>
</html>
Next, create a view for show product detail with the name show.html
on Resources/templates
folder then replace all codes with this.
<!DOCTYPE HTML>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
<title>Show Product</title>
</head>
<body>
<div layout:fragment="content" class="row">
<div class="col-xs-8 col-md-8">
<h3>
<a href="/product" class="btn btn-primary"><span class="glyphicon glyphicon-list"></span> Product</a>
</h3>
<h2 th:text="${product.prodName}"></h2>
<h2><img th:src="${product.prodImage}" width="200" /></h2>
<dl class="list">
<dt>Product Description</dt>
<dd th:text="${product.prodDesc}"></dd>
<dt>Product Description</dt>
<dd th:text="${product.prodPrice}"></dd>
</dl>
<form action="/delete">
<input type="hidden" name="id" th:value="${product.id}" />
<h2><input type="submit" class="btn btn-danger" value="Delete" onclick="return confirm('Are you sure?');" />
<a th:href="@{'/edit/' + ${product.id}}" class="btn btn-warning">Edit</a></h2>
</form>
</div>
</div>
</body>
</html>
Next, create a view for edit product with the name edit.html
on Resources/templates
folder then replace all codes with this.
<!DOCTYPE HTML>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="default">
<head>
<title>Edit Product</title>
</head>
<body>
<div layout:fragment="content" class="row">
<div class="col-xs-8 col-md-8">
<h3>
<a href="/product" class="btn btn-lg btn-primary"><span class="glyphicon glyphicon-list"></span> Product</a>
</h3>
<h2>Edit Product</h2>
<form action="/update">
<div class="form-group">
<label for="email">Product Name:</label>
<input type="text" class="form-control" name="prodName" th:value="${product.prodName}" />
</div>
<div class="form-group">
<label for="email">Product Description</label>
<textarea class="form-control" name="prodDesc" cols="60" rows="3" th:text="${product.prodDesc}"></textarea>
</div>
<div class="form-group">
<label for="email">Product Price</label>
<input type="number" class="form-control" name="prodPrice" th:value="${product.prodPrice}" />
</div>
<div class="form-group">
<label for="email">Product Image URL:</label>
<input type="url" class="form-control" name="prodImage" th:value="${product.prodImage}" />
</div>
<input type="hidden" name="id" th:value="${product.id}" />
<button type="submit" class="btn btn-success">Save</button>
</form>
</div>
</div>
</body>
</html>
Finally, open and edit static HTML file Resources/static/index.html
then replace all codes with this.
<!DOCTYPE HTML>
<html>
<head>
<title>Spring MongoDB Java CRUD Web Application</title>
</head>
<body>
<h2>Spring MongoDB Java CRUD Web Application</h2>
<p><a href="/product">Product List</a></p>
</body>
</html>
This index.html
is the first page that shows up on the browser after Web Application run.
Using Spring Boot, already define the main class for running the application. Just open the terminal or cmd then type this command to run the web application.
./gradlew bootRun
Then open the browser and go to this address http://localhost:8080
and you will get the home page like this.
Just click on the product list
link then you will get the page for do some CRUD operation.
That it’s for now. We are creating this tutorial especially for Java Web newbie, for the master of java we need any suggestion and critics in the comments below. You can find the full and working source code on our GitHub.
Thanks!
#java #springboot #mongodb #webdev