Spring Bootを使ってWebアプリを作成する その2

IndexControllerを作成する。
src/main/java の中にある jp.kpc を右クリックし[新規]-[クラス]を選択する。
名前に「IndexController」と入力し「完了」をクリック。

SpringBoot に対して、このクラスがコントローラであることを教えるために、@Controller アノテーションを追加する。
public class の前の行で「@Cont」を入力してCtrl+スペースを入力すると候補がリストアップされる。
org.springframework.stereotype のControllerを選択する。

package jp.kpc;

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

@Controller
public class IndexController {
	@RequestMapping("/")
	public String index() {
		return "index";
	}
}

SpringBootアプリケーションを起動して、 http://localhost:8080/ にアクセスすると、エラーになるが、先ほどと違うエラーになっていることがわかる。

エラーメッセージを読むと、indexテンプレートが見つからないという意味なので、次はテンプレートを作成する。

src/main/resources の下にある templates を右クリックして[新規]-[その他]を選択する。
「HTMLファイル」を選択し「次へ」をクリック。
ファイル名を index.html にして「次へ」をクリック。
「新規HTMLファイル(5)」を選択して「完了」をクリック。

もうひとつURLのパスを割り当てて、そちらでも index.html を表示してみる。

package jp.kpc;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {
	@RequestMapping("/")
	public String index() {
		return "index";
	}

	@RequestMapping("/form")
	public ModelAndView form(ModelAndView mav) {
		mav.setViewName("index");
		return mav;
	}
}

form.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>診断ページ</title>
</head>
<body>

<h1>診断ページ</h1>

<form action="/form" method="post">
	おなまえ: <input type="text" name="name" />
	<br />
	診断: <input type="text" name="eval" />
	<input type="submit" value="診断" />
</form>


</body>
</html>

IndexController の form メソッドで指定しているテンプレートを form に変更する。

	@RequestMapping("/form")
	public ModelAndView form(ModelAndView mav) {
		mav.setViewName("form");
		return mav;
	}

form メソッドは、GETメソッドだけ受け付けるように指定する。

	@RequestMapping(value="/form", method=RequestMethod.GET)
	public ModelAndView form(ModelAndView mav) {
		mav.setViewName("form");
		return mav;
	}

このように書き換えて再起動すると、http://localhost:8080/form へのアクセスは今まで通りに正常に動作するが、「診断」をクリックするとエラーになる。

form メソッドでGETメソッドだけを受け付けるようにしたために、POSTメソッドを受け取る場所がなくなった。

POSTを受け取るメソッドを用意する。

package jp.kpc;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {
	@RequestMapping("/")
	public String index() {
		return "index";
	}

	@RequestMapping(value="/form", method=RequestMethod.GET)
	public ModelAndView form(ModelAndView mav) {
		mav.setViewName("form");
		return mav;
	}

	@RequestMapping(value="/form", method=RequestMethod.POST)
	public ModelAndView formPost(ModelAndView mav) {
		mav.setViewName("form");
		return mav;
	}

}

POSTメソッドでリクエストパラメータを受け取って、結果を渡してみる。

	@RequestMapping(value="/form", method=RequestMethod.POST)
	public ModelAndView formPost(ModelAndView mav,
			@RequestParam("name") String name,
			@RequestParam("eval") String eval) {
		String result = name + " さんの" + eval + "度は?";
		mav.addObject("result", result);
		mav.setViewName("form");
		return mav;
	}

form.html に結果を表示するタグを追加する。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>診断ページ</title>
</head>
<body>

<h1>診断ページ</h1>

<p th:text="${result}"></p>

<form action="/form" method="post">
	おなまえ: <input type="text" name="name" />
	<br />
	診断: <input type="text" name="eval" />
	<input type="submit" value="診断" />
</form>


</body>
</html>

パーセンテージを計算して結果に追加する。

	@RequestMapping(value="/form", method=RequestMethod.POST)
	public ModelAndView formPost(ModelAndView mav,
			@RequestParam("name") String name,
			@RequestParam("eval") String eval) {
		int percent = (name + eval).hashCode() % 101;
		percent = Math.abs(percent);
		String result = name + " さんの" + eval + "度は" + percent + "%です!!!";
		mav.addObject("result", result);
		mav.setViewName("form");
		return mav;
	}

過去の診断結果も表示できるようにする。

package jp.kpc;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {
	private List<String> list = new ArrayList<String>();

	@RequestMapping("/")
	public String index() {
		return "index";
	}

	@RequestMapping(value="/form", method=RequestMethod.GET)
	public ModelAndView form(ModelAndView mav) {
		mav.setViewName("form");
		return mav;
	}

	@RequestMapping(value="/form", method=RequestMethod.POST)
	public ModelAndView formPost(ModelAndView mav,
			@RequestParam("name") String name,
			@RequestParam("eval") String eval) {
		int percent = (name + eval).hashCode() % 101;
		percent = Math.abs(percent);
		String result = name + " さんの" + eval + "度は" + percent + "%です!!!";
		list.add(result);
		mav.addObject("result", result);
		mav.addObject("list", list);
		mav.setViewName("form");
		return mav;
	}

}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>診断ページ</title>
</head>
<body>

<h1>診断ページ</h1>

<p th:text="${result}"></p>

<form action="/form" method="post">
	おなまえ: <input type="text" name="name" />
	<br />
	診断: <input type="text" name="eval" />
	<input type="submit" value="診断" />
</form>

<hr />

<h3>これまでの診断結果</h3>

<table>
	<tr th:each="result : ${list}">
		<td th:text="${result}"></td>
	</tr>
</table>

</body>
</html>

配布フォルダにある hsqldb フォルダをコピーしてZドライブの適当な場所に貼り付ける。
hsqldb フォルダ内の hsqldb.bat を編集する。

cd data
java -classpath ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 db/shindan --dbname.0 shindan

データベースとの接続を行えるようにするために、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.2.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>jp.kpc</groupId>
	<artifactId>example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>example</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>11</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-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.hsqldb</groupId>
			<artifactId>hsqldb</artifactId>
		</dependency>
	</dependencies>

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

</project>

src/main/resources にある application.properties ファイルを開き、以下の内容を記述する。

spring.datasource.url=jdbc:hsqldb:hsql://localhost/shindan
spring.datasource.username=SA
spring.datasource.password=
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver

jp.kpc を右クリックして[新規]-[クラス]を選択する。
名前に「Shindan」を入力して「完了」をクリック。

以下の内容を入力する。
Eclipseがアノテーションの補完をしてくれない場合は、pom.xml を保存してない可能性があるので、保存を確認!

package jp.kpc;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Entity
public class Shindan {
	@Id
	@GeneratedValue
	@Column
	@NotNull
	private long id;

	@Column
	@NotEmpty
	private String name;

	@Column
	@NotEmpty
	private String eval;

	@Column
	@NotNull
	private int percent;
}

メニューの[ソース]-[getterおよびsetterの生成]を選択する。
「すべて選択」をクリック。
挿入ポイントは「最後のメンバー」を選択し、「完了」をクリック。

すると、自動的にgetter/setter が追加される。

package jp.kpc;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Entity
public class Shindan {
	@Id
	@GeneratedValue
	@Column
	@NotNull
	private long id;

	@Column
	@NotEmpty
	private String name;

	@Column
	@NotEmpty
	private String eval;

	@Column
	@NotNull
	private int percent;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEval() {
		return eval;
	}

	public void setEval(String eval) {
		this.eval = eval;
	}

	public int getPercent() {
		return percent;
	}

	public void setPercent(int percent) {
		this.percent = percent;
	}
}

jp.kpc を右クリックして[新規]-[インターフェース]を選択する。
名前に「ShindanRepository」を入力。
拡張インターフェース「追加」をクリック。
JapRepository を選択して「OK」をクリック。
エラーが出ている T を Shindan に変更、ID を Long に変更して保存する。

package jp.kpc;

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

public interface ShindanRepository extends JpaRepository<Shindan, Long> {

}

コントローラにShindanをデータベースに保存するコードを追加する。

package jp.kpc;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {
	private List<String> list = new ArrayList<String>();
	@Autowired
	private ShindanRepository repository;

	@RequestMapping("/")
	public String index() {
		return "index";
	}

	@RequestMapping(value="/form", method=RequestMethod.GET)
	public ModelAndView form(ModelAndView mav) {
		mav.setViewName("form");
		return mav;
	}

	@RequestMapping(value="/form", method=RequestMethod.POST)
	public ModelAndView formPost(ModelAndView mav,
			@RequestParam("name") String name,
			@RequestParam("eval") String eval) {
		int percent = (name + eval).hashCode() % 101;
		percent = Math.abs(percent);

		Shindan shindan = new Shindan();
		shindan.setName(name);
		shindan.setEval(eval);
		shindan.setPercent(percent);
		repository.saveAndFlush(shindan);

		String result = name + " さんの" + eval + "度は" + percent + "%です!!!";
		list.add(result);
		mav.addObject("result", result);
		mav.addObject("list", list);
		mav.setViewName("form");
		return mav;
	}

}

診断をひとつやってみてから、データベースに接続してみる。
manager.bat をダブルクリックする。
Typeで「HSQL Database Engine Server」を選択する。
URLを「jdbc:hsqldb:hsql://localhost/shindan」にして「OK」をクリック。