/java/

Spring Boot. Simple product list & details base on h2.

2015-12-16 00:23:02

In this tutorial we will create simple product list with details page. Of course we have to start from xml

xml.pom

<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>

<project http:="" maven-4.0.0.xsd&quot;="" maven.apache.org="" xmlns='"http://maven.apache.org/POM/4.0.0"' xmlns:xsi='"http://www.w3.org/2001/XMLSchema-instance"' xsd="" xsi:schemalocation='"http://maven.apache.org/POM/4.0.0'>
<modelversion>4.0.0</modelversion>
<groupid>pl.btbw</groupid>
<artifactid>shopExample</artifactid>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>1.2.7.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-thymeleaf</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-jpa</artifactid>
</dependency>
<dependency>
<groupid>com.h2database</groupid>
<artifactid>h2</artifactid>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
</plugin>
</plugins>
</build>
</project>

The most important class is Entity.

Product.hava

package pl.btbw.core.product;

import javax.persistence.*;

@Entity(name = "product")
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @Column(nullable = false)
    private String name;

    @Column
    private String image;

    @Column(nullable = false)
    private int price;

    @Column
    @Enumerated(EnumType.STRING)
    private ProductStatus status;

    public Product() {
    }

    // get &amp; set

}

As you see here we use Spring Data, with that, to fetch one or fetch list of items we need only this interface.

ProductRepository.java

package pl.btbw.core.product;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository

<product, long=""> {
}

ProductStatus.java

package pl.btbw.core.product;

public enum ProductStatus {

    AVAILABLE, UNAVAILABLE, RESERVED

}

ProductController.java

package pl.btbw.ctrl;

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 pl.btbw.core.product.ProductRepository;

@Controller
public class ProductController {

    @Autowired
    private ProductRepository productRepository;

    @RequestMapping(value = {"/", "/products"})
    public String products(Model model) {

        model.addAttribute("products", productRepository.findAll());

        return "products";
    }

    @RequestMapping(value = {"/product/{id}"})
    public String product(@PathVariable("id") long id, Model model) {

        model.addAttribute("product", productRepository.findOne(id));

        return "product";
    }
}

ah, and this one, the most important Class in Spring Boot word

Application.java

package pl.btbw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

/src/main/resources/templates/layouts/default.html


<!DOCTYPE html>

<html lang='"en"' xmlns:layout='"http://www.ultraq.net.nz/thymeleaf/layout"' xmlns:th='"http://www.thymeleaf.org"'>
<head>
<title></title>
<meta charset="utf-8" content='"text/html;' http-equiv='"Content-Type"'/>
<meta content='"IE=edge"/' http-equiv='"X-UA-Compatible"'/>
<meta content='"width=device-width,' initial-scale='1"/' name='"viewport"'/>
</head>
<body>
<div class='"container"'>
<div ::="" menu&quot;="" th:replace='"fragments/menu'></div>
<div layout:fragment='"content"'>Page content</div>
</div>
</body>
</html>

/src/main/resources/templates/product.html

<!DOCTYPE html>

<html lang='"en"' layout:decorator='"layouts/default"' xmlns:layout='"http://www.ultraq.net.nz/thymeleaf/layout"' xmlns:th='"http://www.thymeleaf.org"'>
<body>
<div layout:fragment='"content"'>
<h1 th:inline='"text"'>Test</h1>
<h1 th:text='"${{product.id}}"'></h1><br/>
<span th:text='"${{product.name}}"'></span><br/>
<span th:text='"${{product.price}}"'></span><br/>
<span th:text='"${{product.status}}"'></span>
</div>
</body>
</html>

/src/main/resources/templates/products.html

<!DOCTYPE html>

<html lang='"en"' layout:decorator='"layouts/default"' xmlns:layout='"http://www.ultraq.net.nz/thymeleaf/layout"' xmlns:th='"http://www.thymeleaf.org"'>
<body>
<div layout:fragment='"content"'>
<h1 th:inline='"text"'>Test</h1>
<tr ${products}&quot;="" :="" th:each='"product'>
<h1 th:text='"${{product.id}}"'></h1>
<span th:text='"${{product.name}}"'></span>
<span th:text='"${{product.price}}"'></span>
<span th:text='"${{product.status}}"'></span>
<a href='"#"' th:href='"@{|/product/${product.id}|}"'>More</a>
<br/>
<br/>
</tr>
</div>
</body>
</html>

of course, application without data is needless

/src/main/resources/data.sql

INSERT INTO product (id, name, image, price, status)
VALUES
  (1, 'Lorem 1', '' ,249, 'AVAILABLE'),
  (2, 'Lorem 2', '' ,249, 'AVAILABLE'),
  (3, 'Lorem 3', '' ,249, 'UNAVAILABLE'),
  (4, 'Lorem 4', '' ,249, 'UNAVAILABLE'),
  (5, 'Lorem 5', '' ,249, 'RESERVED'),
  (6, 'Lorem 6', '' ,249, 'RESERVED'),
;

and that is everything