SpringBootでWebサイトを作る

2022年度システム開発実習

SpringBoot

本棚アプリケーションの作成

投稿日:

SpringBootを使用して本棚アプリケーションを作成する。

新規プロジェクトで springスタータープロジェクト を作成して、pom.xml の以下の箇所を修正する。

プロジェクト名: bookshelf
パッケージ: jp.bookshelf

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.bookshelf</groupId>
	<artifactId>bookshelf</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>bookshelf</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-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.hsqldb</groupId>
			<artifactId>hsqldb</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>

データベースに関する設定

src/main/resources
application.properties

spring.datasource.url=jdbc:hsqldb:file:./db/bookshelf
spring.datasource.username=SA
spring.datasource.password=
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
spring.jpa.hibernate.ddl-auto=update

src/main/java

/bookshelf/{id} にアクセスしたら、その本棚の内容を表示する。

IndexController.java

package jp.bookshelf;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.servlet.ModelAndView;

@Controller
public class IndexController {
	@Autowired
	private BookshelfRepository repository;

	@RequestMapping("/")
	public ModelAndView index(ModelAndView mav) {
		List<Bookshelf> list = repository.findAll();
		mav.setViewName("index");
		mav.addObject("list", list);
		return mav;
	}

	@RequestMapping("/new-bookshelf")
	public ModelAndView shindan2(ModelAndView mav,
			@RequestParam("name") String name) {
		Bookshelf bookshelf = new Bookshelf();
		bookshelf.setName(name);
		repository.saveAndFlush(bookshelf);
		mav.setViewName("bookshelf");
		mav.addObject("bookshelf", bookshelf);
		return mav;
	}

	@RequestMapping("/bookshelf/{id}")
	public ModelAndView bookshelf(ModelAndView mav,
			@PathVariable long id) {
		mav.setViewName("bookshelf");
		Optional<Bookshelf> data = repository.findById(id);
		mav.addObject("bookshelf", data.get());
		return mav;
	}
}

本棚の名前をリンクにしてそれぞれの本棚に飛べるようにする。
本の一覧へのリンクも追加する。

src/main/resources/templates
index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>本棚</title>
</head>
<body>

<h1>本棚</h1>
<p>本棚のリストを表示します。</p>

<ul th:each="bs : ${list}">
	<li>
		<a th:href="@{'/bookshelf/' + ${bs.id}}" th:text="${bs.name}"></a>
	</li>
</ul>

<form class="center" action="/new-bookshelf" method="post">
	名前: <input class="w100" type="text" name="name" />
	<input type="submit" value="追加" />
</form>

<h3><a href="/book">本の一覧</a></h3>

</body>
</html>

src/main/java
BookController.java

package jp.bookshelf;

import java.util.List;
import java.util.Optional;

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

@Controller
public class BookController {
	@Autowired
	private BookRepository repository;
	@Autowired
	private BookshelfRepository bookshelfRepository;

	@RequestMapping(value = "/book", method = RequestMethod.GET)
	public ModelAndView list(ModelAndView mav) {
		mav.addObject("book", new Book());
		mav.setViewName("books");
		List<Book> list = repository.findAll();
		List<Bookshelf> bookshelfs = bookshelfRepository.findAll();
		mav.addObject("list", list);
		mav.addObject("bookshelfs", bookshelfs);
		return mav;
	}

	@RequestMapping(value = "/book", method = RequestMethod.POST)
	public ModelAndView post(ModelAndView mav,
			@ModelAttribute("book") Book book) {
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book");
	}

	@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
	public ModelAndView edit(ModelAndView mav,
			@PathVariable long id) {
		mav.setViewName("edit");
		Optional<Book> data = repository.findById(id);
		mav.addObject("book", data.get());
		return mav;
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	public ModelAndView update(ModelAndView mav,
			@ModelAttribute("book") Book book) {
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book");
	}

}

src/main/resources/templates
books.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>本のリスト</title>
<style type="text/css">
img.book-image {
	width: 100px;
}
</style>
</head>
<body>

<h2>本を追加</h2>
<form action="/book" method="post" th:object="${book}">
	タイトル: <input type="text" name="title" th:value="*{title}" />
	<br />
	著者: <input type="text" name="author" th:value="*{author}" />
	<br />
	画像URL: <input type="text" name="image" th:value="*{image}" />
	<br />
	<input type="submit" value="本を追加" />
</form>

<h1>本のリスト</h1>
<table>
	<tr>
		<th>画像</th><th>タイトル</th><th>著者名</th><th>操作</th><th>本棚</th>
	</tr>
	<tr th:each="book : ${list}">
		<td><img class="book-image" th:src="${book.image}" /></td>
		<td th:text="${book.title}"></td>
		<td th:text="${book.author}"></td>
		<td>
			<a th:href="@{'/edit/' + ${book.id}}">修正</a>
			<a th:href="@{'/delete/' + ${book.id}}">削除</a>
		</td>
		<td>
			本棚<select name="bookshelf">
				<th:block th:each="bookshelf : ${bookshelfs}">
				<option value="${bookshelf.id}" th:text="${bookshelf.name}"></option>
				</th:block>
			</select>に移動する
			<p th:if="${book.bookshelf != null}" th:text="${book.bookshelf.name}">
		</td>
	</tr>
</table>


</body>
</html>

books.html に formタグを追加して、指定した本棚への移動をできるようにする。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>本のリスト</title>
<style type="text/css">
img.book-image {
	width: 100px;
}
</style>
</head>
<body>

<h2>本を追加</h2>
<form action="/book" method="post" th:object="${book}">
	タイトル: <input type="text" name="title" th:value="*{title}" />
	<br />
	著者: <input type="text" name="author" th:value="*{author}" />
	<br />
	画像URL: <input type="text" name="image" th:value="*{image}" />
	<br />
	<input type="submit" value="本を追加" />
</form>

<h1>本のリスト</h1>
<table>
	<tr>
		<th>画像</th><th>タイトル</th><th>著者名</th><th>操作</th><th>本棚</th>
	</tr>
	<tr th:each="book : ${list}">
		<td><img class="book-image" th:src="${book.image}" /></td>
		<td th:text="${book.title}"></td>
		<td th:text="${book.author}"></td>
		<td>
			<a th:href="@{'/edit/' + ${book.id}}">修正</a>
			<a th:href="@{'/delete/' + ${book.id}}">削除</a>
		</td>
		<td>
			<form action="/push" method="post">
				<input type="hidden" name="id" th:value="${book.id}" />
				<select name="bookshelf">
				<th:block th:each="bookshelf : ${bookshelfs}">
				<option th:value="${bookshelf.id}" th:text="${bookshelf.name}"></option>
				</th:block>
			</select>に<button>移動</button>する
			<p th:if="${book.bookshelf != null}" th:text="${book.bookshelf.name}">
			</form>
		</td>
	</tr>
</table>


</body>
</html>

src/main/java
BookController.java

package jp.bookshelf;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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 BookController {
	@Autowired
	private BookRepository repository;
	@Autowired
	private BookshelfRepository bookshelfRepository;

	@RequestMapping(value = "/book", method = RequestMethod.GET)
	public ModelAndView list(ModelAndView mav) {
		mav.addObject("book", new Book());
		mav.setViewName("books");
		List<Book> list = repository.findAll();
		List<Bookshelf> bookshelfs = bookshelfRepository.findAll();
		mav.addObject("list", list);
		mav.addObject("bookshelfs", bookshelfs);
		return mav;
	}

	@RequestMapping(value = "/book", method = RequestMethod.POST)
	public ModelAndView post(ModelAndView mav,
			@ModelAttribute("book") Book book) {
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book");
	}

	@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
	public ModelAndView edit(ModelAndView mav,
			@PathVariable long id) {
		mav.setViewName("edit");
		Optional<Book> data = repository.findById(id);
		mav.addObject("book", data.get());
		return mav;
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	public ModelAndView update(ModelAndView mav,
			@ModelAttribute("book") Book book) {
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book");
	}

	@RequestMapping(value = "/push", method = RequestMethod.POST)
	public ModelAndView push(ModelAndView mav,
			@RequestParam("id") long id,
			@RequestParam("bookshelf") long bookshelfId) {
		Optional<Book> data = repository.findById(id);
		Book book = data.get();
		Optional<Bookshelf> bs = bookshelfRepository.findById(bookshelfId);
		Bookshelf bookshelf = bs.get();
		bookshelf.addBook(book);
		bookshelfRepository.saveAndFlush(bookshelf);
		return new ModelAndView("redirect:/bookshelf/" + bookshelfId);
	}
}

src/main/resources/templates
bookshelf.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>本棚</title>
<style type="text/css">
img.book-image {
	width: 100px;
}
</style>
</head>
<body>

<h1>本棚 : <span th:text="${bookshelf.name}"></span></h1>
<p>この本棚に入っている本のリスト</p>

<table>
	<tr>
		<th>画像</th><th>タイトル</th><th>著者名</th><th>操作</th>
	</tr>
	<tr th:each="book : ${bookshelf.books}">
		<td><img class="book-image" th:src="${book.image}" /></td>
		<td th:text="${book.title}"></td>
		<td th:text="${book.author}"></td>
		<td>
			<a th:href="@{'/edit/' + ${book.id}}">修正</a>
			<a th:href="@{'/delete/' + ${book.id}}">削除</a>
		</td>
	</tr>
</table>

<a href="/">戻る</a>

</body>
</html>

-SpringBoot
-

Copyright© 2022年度システム開発実習 , 2025 All Rights Reserved Powered by STINGER.