Java, Springでショッピングサイトの管理者機能・画面をつくってみた

#はじめに

わたしは、2～3年ほど前からJavaを中心に勉強している者です。
最近になって(遅ればせながら)、Springについて勉強しはじめました。
早速ですが、ショッピングサイトの管理者向け機能・画面を作ってみました。
まだまだ拙いですが、よければ参考にしてみてください。

STSのバージョン : 4.7.0.RELEASE
MySQLのバージョン : 8.0.15
mysql-connector-javaのバージョン ： 8.0.16



```java:SampleApplication.java
package com.example.demo;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


@SpringBootApplication
public class Sample1Application {
	@RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index() {
		
		return "index";
    }
    
	public static void main(String[] args) {
		SpringApplication.run(Sample1Application.class, args);
	}
}

```

```java:SampleController.java
package com.example.demo;


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;


@Controller
public class SampleController {
	@Autowired
	JdbcTemplate jdbcTemplate;
	
	@Autowired
	private SampleService sampleService;
	
	@ModelAttribute
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(Model model) {
		LoginForm loginForm = new LoginForm();
		loginForm.setId("");
		loginForm.setName("");
        model.addAttribute("loginForm", loginForm);
        model.addAttribute("message", "管理者情報を入力してください");
        
        return "login";
    }

	@ModelAttribute
	@RequestMapping(value = "/login_result", method = RequestMethod.POST)
	public String login_result(LoginForm loginForm, Model model) {
		       List<Map<String, Object>> list;
		       list = jdbcTemplate.queryForList("select * from user");
		       
               for(int i = 0; i < list.size(); i++) {
            	   if (("[" + loginForm.getId() + "," + " " + loginForm.getName() + "]").compareTo((list.get(i).values().toString())) == 0) {
            	        model.addAttribute("message", "ログインに成功しました");
                   }
               
                   else {
            	         model.addAttribute("message", "ログインに失敗しました");
                   }
               }

	    	return "login_result";
	}
	
    @ModelAttribute
    @RequestMapping(value = "/admin_menu", method = RequestMethod.GET)
    public String admin_menu(Model model) {
	  model.addAttribute("message", "メニューを選択してください");

    return "admin_menu";
    }
    
    @ModelAttribute
    @RequestMapping(value = "/show_product", method = RequestMethod.GET)
    public String show_product(Model model) {
    	List<String> products = null;
    	products = sampleService.selectAll();
    	model.addAttribute("products",products);
	    model.addAttribute("message", "商品を表示しました");

    return "show_product";
    }
    
    @ModelAttribute
    @RequestMapping(value = "/register_product", method = RequestMethod.GET)
    public String register_product(Model model) {
    	ProductForm productForm = new ProductForm();
    	model.addAttribute("productForm", productForm);
	    model.addAttribute("message", "商品を登録してください");

    return "register_product";
    }

	@ModelAttribute
    @RequestMapping(value = "/update_product", method = RequestMethod.GET)
    public String update_product(Model model) {
      ProductForm productForm = new ProductForm();
      model.addAttribute("productForm", productForm);
	  model.addAttribute("message", "商品を更新してください");

    return "update_product";
    }
	
    @ModelAttribute
    @RequestMapping(value = "/delete_product", method = RequestMethod.GET)
    public String delete_product(Model model) {
      ProductForm productForm = new ProductForm();
      model.addAttribute("productForm", productForm);    	
	  model.addAttribute("message", "商品を削除してください");

    return "delete_product";
    }
    
    @ModelAttribute
    @RequestMapping(value = "/afeter_delete_product", method = RequestMethod.POST)
    public String afeter_delete_product(ProductForm productForm, Model model) {
      sampleService.delete(productForm);	
	  model.addAttribute("message", "処理が完了しました");

    return "afeter_delete_product";
    }
    
    @ModelAttribute
    @RequestMapping(value = "/show_result", method = RequestMethod.POST)
    public String show_result(ProductForm productForm, Model model) {
    	sampleService.insert(productForm);
	    model.addAttribute("message", "処理が完了しました");

    return "show_result";
    }
}
```

```java:SampleService.java
package com.example.demo;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;


@Service
public class SampleService {  
  public List<String> selectAll() {
	  List<String> entities = null;
	  entities = new ArrayList<String>();
	  ResultSet resultSet = null;
	  Connection connection = null;
	  
	  try {
		  connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sample?serverTimezone=JST", "root", "root");
          Statement statement = connection.createStatement();
          resultSet = statement.executeQuery("select * from product");

	  while (resultSet.next()) {
		  String str = resultSet.getString("code") + "  " + resultSet.getString("name") + "  " + resultSet.getString("description") + "  " + resultSet.getString("price") + "  " + resultSet.getString("evaluation");
		  entities.add(str);
	  }

		if (connection != null) {
			connection.close();
		}

	  } catch (SQLException e) {
          e.printStackTrace();
	  }
	  
      return entities;
   }
  
  public void insert(ProductForm productForm) {
	  Connection connection = null;
	  
	  try {
		  connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sample?serverTimezone=JST", "root", "root");
		  PreparedStatement statement = connection.prepareStatement("INSERT INTO product VALUES (?, ?, ?, ?, ?)");

		  statement.setString(1, productForm.getCode());
          statement.setString(2, productForm.getName());
          statement.setString(3, productForm.getDescription());
          statement.setString(4, productForm.getPrice());
          statement.setString(5, productForm.getEvaluation());
          
          connection.setAutoCommit(true);
          statement.execute();

		if (connection != null) {
			connection.close();
		}

	  } catch (SQLException e) {
          e.printStackTrace();
	  }
   }

  public void update(ProductForm productForm) {
	  Connection connection = null;
	  
	  try {
		  connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sample?serverTimezone=JST", "root", "root");
		  PreparedStatement statement = connection.prepareStatement("UPDATE product SET code=?, name=?, description=?, price=?, evaluation=? WHERE code=?");

		  statement.setString(1, productForm.getCode());
          statement.setString(2, productForm.getName());
          statement.setString(3, productForm.getDescription());
          statement.setString(4, productForm.getPrice());
          statement.setString(5, productForm.getEvaluation());
          statement.setString(6, productForm.getCode());

          connection.setAutoCommit(true);
          statement.execute();

		if (connection != null) {
			connection.close();
		}

	  } catch (SQLException e) {
          e.printStackTrace();
	  }
   }
  
  public void delete(ProductForm productForm) {
	  Connection connection = null;
	  
	  try {
		  connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/sample?serverTimezone=JST", "root", "root");
		  PreparedStatement statement = connection.prepareStatement("DELETE FROM product WHERE code=?");

          statement.setString(1, productForm.getCode());

          connection.setAutoCommit(true);
          statement.execute();
          
		if (connection != null) {
			connection.close();
		}

	  } catch (SQLException e) {
          e.printStackTrace();
	  }
   }
}
```

```java:LoginForm.java
package com.example.demo;


public class LoginForm {
    private String id;
    private String name;
    
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

```

```java:ProductForm.java
package com.example.demo;


public class ProductForm {
    private String code;
    private String name;
    private String description;
    private String price;
    private String evaluation;
    
	public String getCode() {
		return code;
	}
	
	public void setCode(String code) {
		this.code = code;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public String getDescription() {
		return description;
	}
	
	public void setDescription(String description) {
		this.description = description;
	}
	
	public String getPrice() {
		return price;
	}
	
	public void setPrice(String price) {
		this.price = price;
	}

	public String getEvaluation() {
		return evaluation;
	}
	
	public void setEvaluation(String evaluation) {
		this.evaluation = evaluation;
	}	
}
```

以上のソースファイルをプロジェクトのsrc/main/javaに格納します。


```html:index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p>Spring-Shopsite にようこそ！</p>
<a href="/login" >管理者の方は こちらからどうぞ</a>
</body>
</html>
```

```html:login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
<form th:action="@{/login_result}" th:object="${loginForm}" method="post">  
ID：<input type="text" th:field="*{id}">
<BR/>
お名前：<input type="text" th:field="*{name}"> 
<BR/>
<input type="submit" value="ログイン"/>
<BR/>
</form>
</body>
</html>
```

```html:login_result.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
<div th:if="${#strings.equals(message, 'ログインに成功しました')}">
<a href="/admin_menu">管理者向けメニュー</a>
</div>
<div th:if="${#strings.equals(message, 'ログインに失敗しました')}">
<a href="/login">ログインし直してください</a>
</div>
</body>
</html>
```

```html:admin_menu.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
<a href="/show_product">登録済み全商品の表示</a>
<br/>
<a href="/register_product">商品の登録</a>
<br/>
<a href="/update_product">商品の更新</a>
<br/>
<a href="/delete_product">商品の削除</a>
</body>
</html>
```

```html:show_product.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
<table th:each="product : ${products}">
<tr>
<td>
<p th:text="${product}"></p>
</td>
</tr>
</table>
</body>
</html>
```

```html:register_product.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
<form th:action="@{/show_result}" th:object="${productForm}" method="post">
 商品コード：<input type="text" th:field="*{code}">
<BR />
商品名：<input type="text" th:field="*{name}">
<BR />
 説明 ：<input type="text" th:field="*{description}">
<BR />
価格：<input type="text" th:field="*{price}">
<BR />
評価：<input type="text" th:field="*{evaluation}">
<BR />
<input type="submit" value="登録"/>
<BR />
</form>
</body>
</html>
```

```html:update_product.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
<form th:action="@{/show_result}" th:object="${productForm}" method="post">
 商品コード：<input type="text" th:field="*{code}">
<BR />
商品名：<input type="text" th:field="*{name}">
<BR />
 説明 ：<input type="text" th:field="*{description}">
<BR />
価格：<input type="text" th:field="*{price}">
<BR />
評価：<input type="text" th:field="*{evaluation}">
<BR />
<input type="submit" value="更新"/>
<BR />
</form>
</body>
</html>
```

```html:delete_product.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
<form th:action="@{/afeter_delete_product}" th:object="${productForm}" method="post">
 商品コード：<input type="text" th:field="*{code}">
<BR />
<input type="submit" value="削除"/>
<BR />
</form>
</body>
</html>
```

```html:after_delete_product.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
</body>
</html>
```

```html:show_result.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Spring-Shopsite</title>
</head>
<body>
<p th:text="${message}"></p>
</body>
</html>
```

以上のテンプレートファイルをsrc/main/resources配下のtemplatesに格納します。



#おわりに

あとはプロジェクトをビルドすれば正常に実行されるはずです。今回の
プロジェクトでは残念ながら、商品の画像は取り扱いできませんが、基本的な機能だけは押さえたつもりです。
もしかしたら、このプロジェクトの続きをやることになるかもしれませんが、その時はまたよろしくお願いいたします。
それではまたお会いしましょう。



#ついでに

念のためpomも載せておきます。

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>Sample-1</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Sample-1</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
    
</project>
```