Java Spring MVC - Tutorial #1

Firman Pro
Java Spring MVC
Published in
9 min readFeb 7, 2018

Pada pembahasan ini, Saya akan sharing beberapa tutorial Java Web dengan menggunakan Spring Framework, sekaligus jadi dokumentasi apa aja Saya pelajari dari buku “Spring: Developing Java Applications for the Enterprise” 😅. So, tenang aja, Saya usahakan membuat pembahasan mudah dipahami bagi pemula, kalau masih susah yah silahkan tanya aja dikomen 😆

Spring Framework

Framework Spring merupakan open source framework berbasis bahasa pemograman Java yang dapat digunakan untuk membangun aplikasi Java CUI (Command User Interface), GUI (Graphical User Interface) dan berbasis Web yang berjalan pada Browser.

Asumsi Telah Install Tools di bawah ini:

Membuat Project Baru

Buka STS lalu project baru dengan memilih menu pada navigasi File-New-Maven Project. Maven adalah sebuah build automation tool untuk mengkonfigurasi Project serta mereferensikan library atau file Jar yang akan kita gunakan pada project.

Beri Ceklist pada “Create a simple project”.

Selanjutnya isi data Group id, Artifact Id.

Sedikit Pembahasan Tentang HSQL DB

Pada pembahasan tutorial ke #1, Saya menggunakan database HSQLDB atau HyperSQL. HSQLDB merupakan sebuah toolkit untuk menjalankan penyimpanan data berbasis Java. HSQLDB dapat dijalankan tanpa membutuhkan sebuah IDEA. Seperti contoh database MySQL dapat kita kelola dengan menggunakan SQLWorkbench, PhpMyAdmin pada XAMPP, atau SQLyog dan lainnya. Oke lanjut… 😁

Kongfigurasi POM.XML

Lalu pada buka file pom.xml . POM singkatan dari Project Object Model, dimana file ini berfungsi untuk menyimpan kongfigurasi Maven project.

Isi source code di bawah ini dalam file pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.firmanpro</groupId>
<artifactId>PhoneStore</artifactId>
<version>0.0.1-SNAPSHOT</version>

<!-- add this - begin -->
<packaging>war</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
<!-- end -->

</project>

Jika terdapat error pada project seperti di bawah ini. Kita hanya perlu melakukan klik kanan pada project PhoneStore - Pilih Maven - Update Porject.

Membuat Halaman Welcome

Seperti halnya sebuah Web tentunya pembuatan halaman dengan menggunakan bahasa pemograman Web yakni HTML. Namun untuk pemograman Web Java file page akan diberi extensi JSP. File-file JSP ini akan diletakan di dalam folder webapp yang berlokasi di src/main/webapp.

Pada webapp, buat folder WEB-INF dan di dalam WEB-INF terdapat folder views. Caranya Klik Kanan Project -New-Folder, lalu beri nama WEB-INF/views.

Selanjutnya buat file JSP dengan cara Klik kanan Project-New-Other. Pada kotak pencarian ketik JSP, lalu pilih JSP File, klik Next, isi nama welcome.jsp dan klik Finish.

Pada File welcome.jsp isi dengan source code di bawah:

<%@ 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>Welcome</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="jumbotron">
<h1> ${greeting} </h1>
<p> ${tagline} </p>
</div>
</body>
</html>

Variabel ${greeting} dan ${tagline} akan diisi nantinya oleh sebuah Controller.

Membuat Controller Welcome

Selanjutnya membuat controller untuk memunculkan File welcome.JSP di atas. Klik kanan Project-New-Class, isi dengan nama Class HomeController dan Package com.firmanpro.phonestore.controller.

Pada HomeController.java terdapat RequestMapping dapat diisi dengan code berikut jika ingin address project http://localhost:8080/PhoneStore/welcome

@RequestMapping("/welcome")

Cara di bawah jika ingin address http://localhost:8080/PhoneStore/ atau pun http://localhost:8080/PhoneStore/welcome

@RequestMapping({"/","/welcome"})

Lengkapnya sebagai berikut:

package com.firmanpro.phonestore.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {

@RequestMapping({"/","/welcome"})
public String welcome(Model model) {
model.addAttribute("greeting","Welcome to Phone Store!");
model.addAttribute("tagline","Online Phone Store");
return "welcome";
}

}

Membuat Config

Buat sebuah File Class dengan nama WebApplicationContextConfig pada src/main/java dengan Package com.firmanpro.phonestore.config, Klik kanan pada Project-New-Class

Pada Class WebApplicationContextConfig.Java isi source code di bawah ini:

package com.firmanpro.phonestore.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
@ComponentScan("com.firmanpro.phonestore")
public class WebApplicationContextConfig extends WebMvcConfigurerAdapter {

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}

@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}

}

Masih dalam package yang sama yaitu com.firmanpro.phonestore.config, buatlah sebuah File java dengan nama DispatcherServletInitializer lalu isi dengan source code:

package com.firmanpro.phonestore.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootApplicationContextConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebApplicationContextConfig.class };
}

@Override
protected String[] getServletMappings() {
return new String[] { "/"};
}

}

Buat File Class dengan nama RootApplicationContextConfig pada package com.firmanpro.phonestore.config. Pada Class ini akan diisi oleh Script Query HSQLDB, akan dijelaskan lebih detail di langkah selanjutnya. Lalu isi dengan source code:

package com.firmanpro.phonestore.config;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;

@Configuration
@ComponentScan("com.firmanpro.phonestore")
public class RootApplicationContextConfig {

@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder
.setType(EmbeddedDatabaseType.HSQL)
.addScript("db/sql/create-table.sql")
.addScript("db/sql/insert-data.sql")
.build();
return db;
}

@Bean
public NamedParameterJdbcTemplate getJdbcTemplate() {
return new NamedParameterJdbcTemplate(dataSource());
}

}

Membuat Object Domain

Obejct Domain adalah sebuah Class yang mewakili data-data sebuah informasi. Buatlah File Class dengan nama Product dan nama Package com.firmanpro.phonestore.domain.

Tips Mengisi Domain

Cara mengisi File Domain Product.java ini sebaiknya dengan cara otomatis dan tidak diketik manual. Pertama kita mengenerate serialVersionUID dengan cara dekatkan kursor pada tulisan Product atau cara lainnya klik icon bohlam kuning. Setelah itu pilih Add generated serial version ID

Sehingga muncul seperti ini:

Lalu tambahkan variable domain source code di bawah ini:

package com.firmanpro.phonestore.domain;

import java.io.Serializable;
import java.math.BigDecimal;

public class Product implements Serializable {

private static final long serialVersionUID = -275596349732196160L;

private String productId;
private String name;
private BigDecimal unitPrice;
private String description;
private String manufacturer;
private String category;
private long unitsInStock;
private long unitsInOrder;
private boolean discontinued;
private String condition;

public Product() {
super();
}

}

Lalu klik kanan pada di dalam Class Product.java, pilih Source-Generate Constructure using Fields.

Lalu Ceklis Field productId, name dan unitPrice. Lalu klik Ok

Dengan cara yang sama klik kanan pada di dalam Class Product.java, pilih Source-Generate Getter and Setter. Ceklis semua Field.

Selanjutnya masih cara yang sama klik kanan pada di dalam Class Product.java, pilih Source-Generate hashCode() and equals() lalu Ceklis 1 Field yaitu productId saja.

Lengkapnya sebagai berikut:

package com.firmanpro.phonestore.domain;import java.io.Serializable;
import java.math.BigDecimal;
public class Product implements Serializable {private static final long serialVersionUID = -275596349732196160L;private String productId;
private String name;
private BigDecimal unitPrice;
private String description;
private String manufacturer;
private String category;
private long unitsInStock;
private long unitsInOrder;
private boolean discontinued;
private String condition;

public Product() {
super();
}
public Product(String productId, String name, BigDecimal unitPrice) {
super();
this.productId = productId;
this.name = name;
this.unitPrice = unitPrice;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(BigDecimal unitPrice) {
this.unitPrice = unitPrice;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public long getUnitsInStock() {
return unitsInStock;
}
public void setUnitsInStock(long unitsInStock) {
this.unitsInStock = unitsInStock;
}
public long getUnitsInOrder() {
return unitsInOrder;
}
public void setUnitsInOrder(long unitsInOrder) {
this.unitsInOrder = unitsInOrder;
}
public boolean isDiscontinued() {
return discontinued;
}
public void setDiscontinued(boolean discontinued) {
this.discontinued = discontinued;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((productId == null) ? 0 : productId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Product other = (Product) obj;
if (productId == null) {
if (other.productId != null)
return false;
} else if (!productId.equals(other.productId))
return false;
return true;
}
}}

Membuat Repository

Repository berfungsi sebagai Class yang akan mengakses obejk domain Product.java. Sebelumnya kita telah membuat File Class dengan nama RootApplicationContextConfig.java, File ini berfungsi membaca query database HSQL.

Buatlah folder db di dalam src/main/resources lalu di dalam folder db buat folder sql. Selanjutnya di dalam folder sql, buatlah file create-table.sql dengan cara klik kanan Project-New-File, lalu isi dengan source code berikut:

DROP TABLE PRODUCTS IF EXISTS;

CREATE TABLE PRODUCTS (
ID VARCHAR(25) PRIMARY KEY,
NAME VARCHAR(50),
DESCRIPTION VARCHAR(250),
UNIT_PRICE DECIMAL,
MANUFACTURER VARCHAR(50),
CATEGORY VARCHAR(50),
CONDITION VARCHAR(50),
UNITS_IN_STOCK BIGINT,
UNITS_IN_ORDER BIGINT,
DISCONTINUED BOOLEAN
);

Masih pada folder sql, buatlah file insert-data.sql dengan cara klik kanan Project-New-File, lalu isi dengan source code berikut:

INSERT INTO PRODUCTS VALUES ('P1234', 'iPhone 6s',
'Apple iPhone 6s smartphone with 4.00-inch 640x1136 display and 8-megapixel rear camera','500','Apple','Smartphone','New',450,0,false);

INSERT INTO PRODUCTS VALUES ('P1235', 'Dell Inspiron',
'Dell Inspiron 14-inch Laptop (Black) with 3rd Generation Intel Core processors',
700,'Dell','Laptop','New',1000,0,false);

INSERT INTO PRODUCTS VALUES ('P1236', 'Nexus 7',
'Google Nexus 7 is the lightest 7 inch tablet With a quad-core Qualcomm Snapdragon™ S4 Pro processor',
300,'Google','Tablet','New',1000,0,false);

Sehingga membentuk struktur seperti berikut:

Buatlah File Class ProductRepository dengan nama Package com.firmanpro.phonestore.domain.repository, lalu isi:

package com.firmanpro.phonestore.domain.repository;

import java.util.List;

import com.firmanpro.phonestore.domain.Product;

public interface ProductRepository {

List <Product> getAllProducts();

}

Buatlah File Class InMemoryProductRepository dengan nama Package com.firmanpro.phonestore.domain.repository.impl, lalu isi:

package com.firmanpro.phonestore.domain.repository.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import com.firmanpro.phonestore.domain.Product;
import com.firmanpro.phonestore.domain.repository.ProductRepository;

@Repository
public class InMemoryProductRepository implements ProductRepository {

@Autowired
private NamedParameterJdbcTemplate jdbcTemplate;

@Override
public List<Product> getAllProducts() {
Map<String, Object> params = new HashMap<String, Object>();
List<Product> result = jdbcTemplate.query("SELECT * FROM products", params, new ProductMapper());
return result;
}

private static final class ProductMapper implements RowMapper<Product> {
public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
Product product = new Product();
product.setProductId(rs.getString("ID"));
product.setName(rs.getString("NAME"));
product.setDescription(rs.getString("DESCRIPTION"));
product.setUnitPrice(rs.getBigDecimal("UNIT_PRICE"));
product.setManufacturer(rs.getString("MANUFACTURER"));
product.setCategory(rs.getString("CATEGORY"));
product.setCondition(rs.getString("CONDITION"));
product.setUnitsInStock(rs.getLong("UNITS_IN_STOCK"));
product.setUnitsInOrder(rs.getLong("UNITS_IN_ORDER"));
product.setDiscontinued(rs.getBoolean("DISCONTINUED"));
return product;
}
}

}

Membuat Controller Product

Buatlah File Class dengan nama ProductController dan package com.firmanpro.phonestore.controller, lalu isi dengan source code berikut:

package com.firmanpro.phonestore.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.firmanpro.phonestore.domain.repository.ProductRepository;

@Controller
public class ProductController {

@Autowired
private ProductRepository productRepository;

@RequestMapping("/products")
public String list(Model model) {
model.addAttribute("products", productRepository.getAllProducts());
return "products";
}

}

Selanjutnya buatlah halaman JPS dengan nama products pada src/main/webapp/WEB-INF/views. Lalu isi source code berikut:

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

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet"
href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<title>Products</title>
</head>
<body>
<section>
<div class="jumbotron">
<div class="container">
<h1>Products</h1>
<p>The available Phone in our Store</p>
</div>
</div>
</section>

<section class="container">
<div class="row">
<c:forEach items="${products}" var="product">
<div class="col-sm-6 col-md-3">
<div class="thumbnail">
<div class="caption">
<h3>${product.name}</h3>
<p>${product.description}</p>
<p>$${product.unitPrice}</p>
<p>Available ${product.unitsInStock} units in stock</p>
</div>
</div>
</div>
</c:forEach>
</div>
</section>
</body>
</html>

Seluruh strukture file sebagai berikut:

Time To Run

Tahap ini menjalankan web yang telah kita rancang ke browser dengan menggunakan web server Tomcat. Klik kanan Project-Run As-Run on Server

Pilih server yang telah dibuat, klik Finish:

Hasil Pada Browser

Lanjut ke tutorial #2

--

--