はじめに
どうも、プログラミング勉強中の大学生、@Ikuto19です。今回は前回の続き(part2)からやっていこうと思います。
前回のおさらい
part2では、作成手順1~3までを行いました。今回は作成手順4~5の2つをやろうかなと思います。
以下が今回、新規作成(赤)または修正(青)するものです。
ホーム画面からの画面遷移の実装
ホーム画面となるindex.htmlから、登録・削除を行うoperateCollate.htmlへ画面遷移する仕組みを実装します。
新規ファイルの作成・既存ファイルの修正
OperateController.java
URLに対応してoperateCollate.htmlを表示します。その際、index.htmlのページのテキストボックスから入力された文字列型のISBNコードをoperateCollate.htmlにModelMapというクラスを用いて渡します。第一引数に変数名、第二引数に渡したい文字列を入れます。個人的にここの変数名は統一すべきだと思っています。
package com.app.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class OperateController {
@GetMapping("/index")
public String getIndexPage(Model model) {
return "index";
}
//以下追加するメソッド
@RequestMapping("/operateCollate")
public String operateCollate(ModelMap modelMap, @RequestParam("isbn") String isbn) {
modelMap.addAttribute("isbn", isbn);
return "operateCollate";
}
}
noImage.png
こちらからダウンロード
ダウンロード後、「noImage.png」に変更してください。
bookInfo.js
この方のプログラムを今回の目的に応じて変更しています。
openBD の API で ISBN をキーに書誌情報を取得する ( jQuery 使用 )
入力されたISBNコードを元に書籍情報をjson形式で取得し、今回は下記の情報のみ取得しています。タイトル・出版社・著者の情報がない場合は "なし" を格納し、表紙がない場合はNo Imageと書かれたpngファイルのurlを格納しています。
- 書籍タイトル → title
- 出版社 → publisher
- 著者 → author
- 表紙 →thumbnail
$(function () {
const isbn = $("#isbn").val();
const url = "https://api.openbd.jp/v1/get?isbn=" + isbn;
$.getJSON(url, function (data) {
var title = 'なし';
var publisher = 'なし';
var author = 'なし';
var thumbnail = '../images/noImage.png';
if (data[0] != null) {
if (data[0].summary.cover == "") {
$("#thumbnail_image").html('<img src=\"' + thumbnail + '\" style=\"border:solid 1px #000000\" />');
} else {
$("#thumbnail_image").html('<img src=\"' + data[0].summary.cover + '\" style=\"border:solid 1px #000000\" />');
thumbnail = data[0].summary.cover;
}
title = data[0].summary.title;
publisher = data[0].summary.publisher;
author = data[0].summary.author;
}else{
$("#thumbnail_image").html('<img src=\"' + thumbnail + '\" style=\"border:solid 1px #000000\" />');
}
$("#title").val(title);
$("#publisher").val(publisher);
$("#author").val(author);
$("#thumbnail").val(thumbnail);
});
});
operateCollate.html
書籍の問い合わせ終了後、取得した情報を表示して登録もしくは削除するページです。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<script th:src="@{/webjars/jquery/3.1.1/jquery.min.js}"></script>
<script type="text/javascript" src="/js/bookInfo.js"
th:src="@{/js/bookInfo.js}"></script>
<meta charset="UTF-8">
<title>書籍管理アプリ</title>
</head>
<body>
<div class="main_containerCollate background">
<form method="get" action="regist">
<div class="flexbox">
<div class="">
<div class="info">
ISBN:<input id="isbn" class="texts" type="text" name="isbn" th:value="${isbn}"
autofocus>
</div>
<div class="info">
書籍名:<input id="title" class="texts" type="text" name="title" value="">
</div>
<div class="info">
出版社:<input id="publisher" class="texts" type="text" name="publisher" value="">
</div>
<div class="info">
著者:<input id="author" class="texts" type="text" name="author" value="">
</div>
</div>
<div class="">
<p id="thumbnail_image"></p>
<input hidden id="thumbnail" type="text" name="thumbnail" value="">
</div>
</div>
<div class="info">
<p>上記の書籍について、下記を選択してください.</p>
<button type="submit" class="submit">登録</button>
<button type="submit" class="submit" formaction="delete">削除</button>
</div>
</form>
<div class="link">
<a href="/index">戻る</a>
</div>
</div>
</body>
</html>
pom.xml
下記の依存関係を追加します。jQueryを使うためのライブラリです。
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1</version>
</dependency>
データベースへの登録と削除の実装
OperateController.java
下記のフィールド変数とメソッドをOperateController.javaに追加
- フィールド: isbnRepository → リポジトリ
- メソッド: regist() → データベースへの登録メソッド
- メソッド: delete() → データベースの削除メソッド
取得した情報をISBNオブジェクトにセットし、DatabaseClassクラスを使って表示するメッセージを取得している。
package com.app.controller;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.app.database.DatabaseClass;
import com.app.entity.ISBN;
import com.app.repository.ISBNRepository;
@Controller
public class OperateController {
@Autowired
ISBNRepository isbnRepository;
@RequestMapping("/operateCollate")
public String operateCollate(ModelMap modelMap, @RequestParam("isbn") String isbn) {
modelMap.addAttribute("isbn", isbn);
return "operateCollate";
}
@RequestMapping("regist")
public String regist(ModelMap modelMap, @RequestParam("isbn") String isbn,
@RequestParam("title") String title, @RequestParam("publisher") String publisher,
@RequestParam("author") String author, @RequestParam("thumbnail") String thumbnail) throws SQLException {
ISBN isbnInfo = new ISBN();
isbnInfo.setIsbn(isbn);
isbnInfo.setTitle(title);
isbnInfo.setPublisher(publisher);
isbnInfo.setAuthor(author);
isbnInfo.setThumbnail(thumbnail.replace("https://cover.openbd.jp/", ""));
DatabaseClass dc = new DatabaseClass(isbnRepository.findAll());
String message = dc.registDB(isbnInfo,isbnRepository);
modelMap.addAttribute("message",message);
return "regist";
}
@RequestMapping("delete")
public String delete(ModelMap modelMap, @RequestParam("isbn") String isbn,
@RequestParam("title") String title, @RequestParam("publisher") String publisher,
@RequestParam("author") String author, @RequestParam("thumbnail") String thumbnail) throws SQLException {
ISBN isbnInfo = new ISBN();
isbnInfo.setIsbn(isbn);
isbnInfo.setTitle(title);
isbnInfo.setPublisher(publisher);
isbnInfo.setAuthor(author);
isbnInfo.setThumbnail(thumbnail.replace("https://cover.openbd.jp/", ""));
DatabaseClass dc = new DatabaseClass(isbnRepository.findAll());
String message = dc.deleteDB(isbnInfo,isbnRepository);
modelMap.addAttribute("message",message);
return "delete";
}
}
DatabaseClass.java
データの型の加工や状況によって変わるメッセージの生成を行うクラス。
- registDB()メソッド → データベースと比較して登録と登録用メッセージの生成
- deleteDB()メソッド → データベースと比較して削除と削除用メッセージの生成
- convertStrings()メソッド → ISBNオブジェクトを文字列のISBNコードとして変換
package com.app.database;
(import文の省略)
public class DatabaseClass {
private List<ISBN> manageBookDB;
public DatabaseClass(List<ISBN> manageBookDB) {
this.manageBookDB = manageBookDB;
}
public String registDB(ISBN isbnInfo, ISBNRepository isbnRepository) throws SQLException {
String message = null;
if(isbnInfo.getTitle().equals("なし") || isbnInfo.getPublisher().equals("なし") || isbnInfo.getAuthor().equals("なし")){
message = "書籍情報を取得できなかったので、登録できませんでした.";
}else if(convertStrings(manageBookDB).contains(isbnInfo.getIsbn())) {
message = "すでにデータベースに存在します.";
} else {
message = "新しくデータベースに登録しました.";
isbnRepository.save(isbnInfo);
}
return message;
}
public String deleteDB(ISBN isbnInfo, ISBNRepository isbnRepository) throws SQLException {
String message = null;
if(convertStrings(manageBookDB).contains(isbnInfo.getIsbn())) {
message = "データベースから削除しました.";
isbnRepository.delete(isbnInfo);
}else {
message = "データベースに存在しません.";
}
return message;
}
public List<String> convertStrings(List<ISBN> manageBook){
List<String> isbnList = new ArrayList<String>();
for(ISBN isbn:manageBook) {
isbnList.add(isbn.getIsbn());
}
return isbnList;
}
}
ISBN.java
LoginUser.javaと同じエンティティクラス。
package com.app.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "isbn_code")
public class ISBN {
@Id
@Column(name = "isbn")
private String isbn;
@Column(name = "title")
private String title;
@Column(name = "publisher")
private String publisher;
@Column(name = "author")
private String author;
@Column(name = "thumbnail")
private String thumbnail;
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getThumbnail() {
return thumbnail;
}
public void setThumbnail(String thumbnail) {
this.thumbnail = thumbnail;
}
}
ISBNRepository.java
package com.app.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.app.entity.ISBN;
@Repository
public interface ISBNRepository extends JpaRepository<ISBN, String>{}
delete.html
削除を行うページ。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>削除ページ</title>
</head>
<body>
<div class="main_container do">
<div class=title>
<h1>書籍削除</h1>
</div>
<div class="message">
<p th:text="${message}"></p>
</div>
<div>
<a href="index">戻る</a>
</div>
</div>
</body>
</html>
regist.html
登録を行うページ。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登録ページ</title>
</head>
<body>
<div class="main_container do">
<div class=title>
<h1>書籍登録</h1>
</div>
<div class="message">
<p th:text="${message}"></p>
</div>
<div>
<a href="index">戻る</a>
</div>
</div>
</body>
</html>
書籍情報データベースの構築
以下のコマンドで書籍情報を保存するテーブルを作成します。テーブル名はエンティティクラスであるISBN.javaの@Table(name = "〇〇")
の〇〇と同じにします。今回はisbn_codeというテーブル名にしました。
$ mysql -u (mysqlのユーザー名) -p
Enter password: (mysqlのパスワード)
mysql> use manageBook
mysql> create table isbn_code(,isbn varchar(256),title varchar(256),publisher varchar(256),author varchar(256),thumbnail varchar(256));
動作確認
http://localhost:8080/login にアクセス後、前回設定したログイン用のusernameとpasswordを入力してください。ISBNコードを入力して登録ボタンや削除ボタンを押すとデータベースから登録または削除ができるかと思います。データベースを確認する際は以下のコマンドで確認してください。
$ mysql -u (mysqlのユーザー名) -p
Enter password: (mysqlのパスワード)
mysql> create database manageBook;
mysql> use manageBook
mysql> select * from isbn_code;
終わりに
今回はここまでにします。今回で最後と書いたのですが、長くなりそうなので分割しました。次回が本当に最後で、残りの部分(herokuの設定やデプロイなど)を作っていこうと思います。
次回へ続く(part final) > 近々投稿