Bookshelfアプリを作成する (Update)

CRUDのうち、CreateとReadは動いているので、次はUpdateを作ってみる。

BookContoller.java

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

editbookテンプレートを作成する。

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

<a href="/">トップ</a>

<h1>本の編集</h1>

<form action="/book/edit" method="post">
	<div>タイトル: <input type="text" name="title" th:value="${book.title}" /></div>
	<div>著者: <input type="text" name="author" th:value="${book.author}" /></div>
	<div><input id="submit" type="submit" value="修正" /></div>
</form>


</body>
</html>

サーバーを再起動して /book/edit/{id} にアクセスすると、本の編集画面を表示する。

POSTメソッドのリクエストを受け取るところは作ってないので「修正」ボタンを押すとエラーになる。

コントローラでPOSTメソッドを受け取れるようにする。

	@RequestMapping(value = "/book/edit", method = RequestMethod.POST)
	public ModelAndView edit(ModelAndView mav,
			@RequestParam("id") long id,
			@RequestParam("title") String title,
			@RequestParam("author") String author) {
		Optional<Book> data = repository.findById(id);
		Book book = data.get();
		book.setTitle(title);
		book.setAuthor(author);
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book/" + id);
	}

再起動して「修正」ボタンを押すとエラー表示になる。
エラーメッセージを読むと、リクエストパラメータにidが存在しないと言っているので、入力フォームに追加する。

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

<a href="/">トップ</a>

<h1>本の編集</h1>

<form action="/book/edit" method="post">
	<input type="hidden" name="id" th:value="${book.id}" />
	<div>タイトル: <input type="text" name="title" th:value="${book.title}" /></div>
	<div>著者: <input type="text" name="author" th:value="${book.author}" /></div>
	<div><input id="submit" type="submit" value="修正" /></div>
</form>


</body>
</html>

book.html に修正画面へのリンクを追加する。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Book - 本を入れる本棚を指定する</title>
</head>
<body>

<h1>Book</h1>

<a href="/">トップ</a>

<table>
	<tr>
		<td th:text="${book.title}"></td>
		<td th:text="${book.author}"></td>
		<td><a th:href="@{'/book/edit/' + ${book.id}}" th:text="修正"></a></td>
	</tr>
</table>
:

本の画像を表示できるようにする。

package jp.kpc;

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

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

	@Column
	@NotEmpty
	private String title;

	@Column
	@NotEmpty
	private String author;

	@Column
	private String image;

	@ManyToOne
	private Bookshelf bookshelf;

	public long getId() {
		return id;
	}

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

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public Bookshelf getBookshelf() {
		return bookshelf;
	}

	public void setBookshelf(Bookshelf bookshelf) {
		this.bookshelf = bookshelf;
	}

	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

}

コントローラで画像URLも保存するように修正する。

	@RequestMapping(value = "/book/edit", method = RequestMethod.POST)
	public ModelAndView edit(ModelAndView mav,
			@RequestParam("id") long id,
			@RequestParam("title") String title,
			@RequestParam("author") String author,
			@RequestParam("image") String image) {
		Optional<Book> data = repository.findById(id);
		Book book = data.get();
		book.setTitle(title);
		book.setAuthor(author);
		book.setImage(image);
		repository.saveAndFlush(book);
		return new ModelAndView("redirect:/book/" + id);
	}

editbook.html テンプレート内で画像を表示する。

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

<a href="/">トップ</a>

<h1>本の編集</h1>

<img th:src="${book.image}" width="200" />

<form action="/book/edit" method="post">
	<input type="hidden" name="id" th:value="${book.id}" />
	<div>タイトル: <input type="text" name="title" th:value="${book.title}" /></div>
	<div>著者: <input type="text" name="author" th:value="${book.author}" /></div>
	<div>画像URL: <input type="text" name="image" th:value="${book.image}" /></div>
	<div><input id="submit" type="submit" value="修正" /></div>
</form>


</body>
</html>

book.html テンプレートにも画像を追加。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Book - 本を入れる本棚を指定する</title>
</head>
<body>

<h1>Book</h1>

<a href="/">トップ</a>


<table>
	<tr><td><img th:src="${book.image}" width="100" /></td></tr>
	<tr>
		<td th:text="${book.title}"></td>
		<td th:text="${book.author}"></td>
		<td><a th:href="@{'/book/edit/' + ${book.id}}" th:text="修正"></a></td>
	</tr>
</table>
:

books.html テンプレートにも画像を追加。

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

<h1>Book list</h1>

<a href="/">トップ</a>

<table>
	<tr>
		<th>ID</th><th>画像</th><th>タイトル</th><th>著者</th><th>本棚</th>
	</tr>
	<tr th:each="book : ${list}">
		<td th:text="${book.id}"></td>
		<td><img th:src="${book.image}" height="50" /></td>
		<td><a th:href="@{'/book/' + ${book.id}}" th:text="${book.title}"></a></td>
		<td th:text="${book.author}"></td>
		<td th:if="${book.bookshelf != null}" th:text="${book.bookshelf.name}"></td>
		<td th:if="${book.bookshelf == null}" th:text="本棚に入れてません"></td>
	</tr>
</table>