From cdfdef6d9319ae4b4ada47b6dac70c6b81c19607 Mon Sep 17 00:00:00 2001
From: o-matsuda <26-o-matsuda-stellatecnica@it-college.co.jp>
Date: Tue, 20 Oct 2026 12:46:26 +0900
Subject: [PATCH 1/4] =?UTF-8?q?html=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/resources/templates/application.html | 37 +++++++++++++++++++
.../templates/applicationConfirm.html | 37 +++++++++++++++++++
2 files changed, 74 insertions(+)
create mode 100644 book-rent/src/main/resources/templates/application.html
create mode 100644 book-rent/src/main/resources/templates/applicationConfirm.html
diff --git a/book-rent/src/main/resources/templates/application.html b/book-rent/src/main/resources/templates/application.html
new file mode 100644
index 0000000..de80674
--- /dev/null
+++ b/book-rent/src/main/resources/templates/application.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+ 書籍貸出申請画面
+
+
+
+
+
+ 書籍一覧に戻る
+
+
+
\ No newline at end of file
diff --git a/book-rent/src/main/resources/templates/applicationConfirm.html b/book-rent/src/main/resources/templates/applicationConfirm.html
new file mode 100644
index 0000000..cc28384
--- /dev/null
+++ b/book-rent/src/main/resources/templates/applicationConfirm.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+ 書籍貸出申請画面
+
+
+
+
+
+ 申請情報入力
+
+
+
\ No newline at end of file
From bb34fe164e575e63c8850851fba6bb39545d4414 Mon Sep 17 00:00:00 2001
From: "h.hein" <26-h-kyaw-sakuracommunication@it-college.co.jp>
Date: Tue, 20 Oct 2026 12:47:35 +0900
Subject: [PATCH 2/4] form
---
.../java/com/example/demo/form/BookForm.java | 87 ++++++++++++++-----
1 file changed, 64 insertions(+), 23 deletions(-)
diff --git a/book-rent/src/main/java/com/example/demo/form/BookForm.java b/book-rent/src/main/java/com/example/demo/form/BookForm.java
index d801e04..68f84c4 100644
--- a/book-rent/src/main/java/com/example/demo/form/BookForm.java
+++ b/book-rent/src/main/java/com/example/demo/form/BookForm.java
@@ -1,30 +1,71 @@
package com.example.demo.form;
-
/** 書籍登録・編集フォーム */
public class BookForm {
- private Integer idBook;
- private String isbn = "";
- private String nmBook = "";
- private String knBook = "";
- private String publisher = "";
- private String note = "";
+ private Integer idBook;
+ private String isbn = "";
+ private String nmBook = "";
+ private String knBook = "";
+ private String publisher = "";
+ private String note = "";
- public void trim() {
- isbn = t(isbn); nmBook = t(nmBook); knBook = t(knBook); publisher = t(publisher); note = t(note);
- }
- private static String t(String s) { return s == null ? "" : s.trim(); }
+ public void trim() {
+ isbn = t(isbn);
+ nmBook = t(nmBook);
+ knBook = t(knBook);
+ publisher = t(publisher);
+ note = t(note);
+ }
- public Integer getIdBook() { return idBook; }
- public void setIdBook(Integer v) { this.idBook = v; }
- public String getIsbn() { return isbn; }
- public void setIsbn(String v) { this.isbn = v; }
- public String getNmBook() { return nmBook; }
- public void setNmBook(String v) { this.nmBook = v; }
- public String getKnBook() { return knBook; }
- public void setKnBook(String v) { this.knBook = v; }
- public String getPublisher() { return publisher; }
- public void setPublisher(String v) { this.publisher = v; }
- public String getNote() { return note; }
- public void setNote(String v) { this.note = v; }
+ private static String t(String s) {
+ return s == null ? "" : s.trim();
+ }
+
+ public Integer getIdBook() {
+ return idBook;
+ }
+
+ public void setIdBook(Integer v) {
+ this.idBook = v;
+ }
+
+ public String getIsbn() {
+ return isbn;
+ }
+
+ public void setIsbn(String v) {
+ this.isbn = v;
+ }
+
+ public String getNmBook() {
+ return nmBook;
+ }
+
+ public void setNmBook(String v) {
+ this.nmBook = v;
+ }
+
+ public String getKnBook() {
+ return knBook;
+ }
+
+ public void setKnBook(String v) {
+ this.knBook = v;
+ }
+
+ public String getPublisher() {
+ return publisher;
+ }
+
+ public void setPublisher(String v) {
+ this.publisher = v;
+ }
+
+ public String getNote() {
+ return note;
+ }
+
+ public void setNote(String v) {
+ this.note = v;
+ }
}
From 81d722be8d9837c5d9bcdfda5182ced23af4c17d Mon Sep 17 00:00:00 2001
From: "h.hein" <26-h-kyaw-sakuracommunication@it-college.co.jp>
Date: Tue, 20 Oct 2026 13:20:09 +0900
Subject: [PATCH 3/4] Controller (Login / Loan) Html (applicatinList
/erroe/login)
---
.../demo/controller/LoanContorller.java | 5 -
.../demo/controller/LoanController.java | 113 ++++++++++
.../demo/controller/LoginController.java | 70 +++++-
.../main/resources/templates/application.html | 37 ----
.../resources/templates/applicationList.html | 34 +++
.../src/main/resources/templates/error.html | 17 ++
.../src/main/resources/templates/login.html | 201 ++++++++++--------
7 files changed, 348 insertions(+), 129 deletions(-)
delete mode 100644 book-rent/src/main/java/com/example/demo/controller/LoanContorller.java
create mode 100644 book-rent/src/main/java/com/example/demo/controller/LoanController.java
delete mode 100644 book-rent/src/main/resources/templates/application.html
create mode 100644 book-rent/src/main/resources/templates/applicationList.html
create mode 100644 book-rent/src/main/resources/templates/error.html
diff --git a/book-rent/src/main/java/com/example/demo/controller/LoanContorller.java b/book-rent/src/main/java/com/example/demo/controller/LoanContorller.java
deleted file mode 100644
index 2e5d21b..0000000
--- a/book-rent/src/main/java/com/example/demo/controller/LoanContorller.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.example.demo.controller;
-
-public class LoanContorller {
-
-}
diff --git a/book-rent/src/main/java/com/example/demo/controller/LoanController.java b/book-rent/src/main/java/com/example/demo/controller/LoanController.java
new file mode 100644
index 0000000..192665a
--- /dev/null
+++ b/book-rent/src/main/java/com/example/demo/controller/LoanController.java
@@ -0,0 +1,113 @@
+package com.example.demo.controller;
+
+
+
+import java.util.List;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.SessionAttribute;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.example.demo.common.BusinessException;
+import com.example.demo.common.Const;
+import com.example.demo.common.LoginUser;
+import com.example.demo.service.LoanService;
+
+/** LOAN-01:書籍貸出申請(一般ユーザーのみ)。入力 → 確認 → 完了 */
+@Controller
+@RequestMapping("/loan")
+public class LoanController {
+ private final LoanService loanService;
+
+ public LoanController(LoanService loanService) {
+ this.loanService = loanService;
+ }
+
+ /** 書籍一覧 →(申請ボタン)→ 申請入力 */
+ @GetMapping("/apply")
+ public String input(@RequestParam Integer idBook,
+ @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser user,
+ Model model, RedirectAttributes ra) {
+ return showInput(idBook, "", "", List.of(), user, model, ra);
+ }
+
+ /** 確認画面 →(申請情報入力に戻る)→ 申請入力(入力値を保持) */
+ @PostMapping("/apply/input")
+ public String back(@RequestParam Integer idBook,
+ @RequestParam(defaultValue = "") String dateBorrow,
+ @RequestParam(defaultValue = "") String dateScheduledReturn,
+ @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser user,
+ Model model, RedirectAttributes ra) {
+ return showInput(idBook, dateBorrow, dateScheduledReturn, List.of(), user, model, ra);
+ }
+
+ /** 申請入力 →(申請確認)→ 確認 */
+ @PostMapping("/apply/confirm")
+ public String confirm(@RequestParam Integer idBook,
+ @RequestParam(defaultValue = "") String dateBorrow,
+ @RequestParam(defaultValue = "") String dateScheduledReturn,
+ @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser user,
+ Model model, RedirectAttributes ra) {
+ List errors = loanService.validateDates(dateBorrow, dateScheduledReturn);
+ if (!errors.isEmpty()) {
+ return showInput(idBook, dateBorrow, dateScheduledReturn, errors, user, model, ra);
+ }
+ if (user.isAdmin()) return "redirect:/menu";
+ try {
+ model.addAttribute("book", loanService.getLendableBook(idBook));
+ } catch (BusinessException e) {
+ ra.addFlashAttribute("errorMessage", e.getMessage());
+ return "redirect:/books";
+ }
+ model.addAttribute("idBook", idBook);
+ model.addAttribute("dateBorrow", dateBorrow);
+ model.addAttribute("dateScheduledReturn", dateScheduledReturn);
+ return "loanApplyConfirm";
+ }
+
+ /** 確認 →(申請)→ 完了。二重送信防止のため登録後はリダイレクトする(PRG) */
+ @PostMapping("/apply/execute")
+ public String execute(@RequestParam Integer idBook,
+ @RequestParam(defaultValue = "") String dateBorrow,
+ @RequestParam(defaultValue = "") String dateScheduledReturn,
+ @SessionAttribute(Const.SESSION_LOGIN_USER) LoginUser user,
+ RedirectAttributes ra) {
+ if (user.isAdmin()) return "redirect:/menu";
+ try {
+ Integer id = loanService.apply(idBook, dateBorrow, dateScheduledReturn, user);
+ ra.addFlashAttribute("message", "書籍貸出申請が完了しました。(申請ID:" + id + ")");
+ return "redirect:/loan/apply/complete";
+ } catch (BusinessException e) {
+ ra.addFlashAttribute("errorMessage", e.getMessage());
+ return "redirect:/books";
+ }
+ }
+
+ @GetMapping("/apply/complete")
+ public String complete(Model model) {
+ model.addAttribute("backUrl", "/books");
+ model.addAttribute("backLabel", "書籍一覧に戻る");
+ return "complete";
+ }
+
+ private String showInput(Integer idBook, String dateBorrow, String dateScheduledReturn, List errors,
+ LoginUser user, Model model, RedirectAttributes ra) {
+ if (user.isAdmin()) return "redirect:/menu"; // 申請は一般ユーザーのみ
+ try {
+ model.addAttribute("book", loanService.getLendableBook(idBook));
+ } catch (BusinessException e) {
+ ra.addFlashAttribute("errorMessage", e.getMessage());
+ return "redirect:/books";
+ }
+ model.addAttribute("idBook", idBook);
+ model.addAttribute("dateBorrow", dateBorrow);
+ model.addAttribute("dateScheduledReturn", dateScheduledReturn);
+ model.addAttribute("errors", errors);
+ return "loanApplyInput";
+ }
+}
diff --git a/book-rent/src/main/java/com/example/demo/controller/LoginController.java b/book-rent/src/main/java/com/example/demo/controller/LoginController.java
index 5880c4f..81c8dfc 100644
--- a/book-rent/src/main/java/com/example/demo/controller/LoginController.java
+++ b/book-rent/src/main/java/com/example/demo/controller/LoginController.java
@@ -1,5 +1,73 @@
package com.example.demo.controller;
-public class LoginController {
+import java.util.Optional;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpSession;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.example.demo.common.Const;
+import com.example.demo.common.LoginUser;
+import com.example.demo.service.AuthService;
+
+/** AUTH-01:ログイン/ログアウト(login.html) */
+@Controller
+public class LoginController {
+ private final AuthService authService;
+
+ public LoginController(AuthService authService) {
+ this.authService = authService;
+ }
+
+ @GetMapping("/")
+ public String root() {
+ return "redirect:/menu";
+ }
+
+ @GetMapping("/login")
+ public String loginForm(HttpSession session) {
+ if (session.getAttribute(Const.SESSION_LOGIN_USER) != null) {
+ return "redirect:/menu";
+ }
+ return "login";
+ }
+
+ @PostMapping("/login")
+ public String login(@RequestParam(defaultValue = "") String mailAddress,
+ @RequestParam(defaultValue = "") String password,
+ HttpServletRequest request, Model model) {
+ String mail = mailAddress.trim();
+ model.addAttribute("mailAddress", mail); // 入力値を保持(パスワードは保持しない)
+
+ if (mail.isEmpty() || password.isEmpty()) {
+ model.addAttribute("errorMessage", "メールアドレスとパスワードを入力してください。");
+ return "login";
+ }
+ Optional user = authService.authenticate(mail, password);
+ if (user.isEmpty()) {
+ // どちらが誤りかは分からない文言にする
+ model.addAttribute("errorMessage", "メールアドレスまたはパスワードが正しくありません。");
+ return "login";
+ }
+ // セッション固定化攻撃対策:古いセッションを破棄して新規発行
+ HttpSession old = request.getSession(false);
+ if (old != null) {
+ old.invalidate();
+ }
+ request.getSession(true).setAttribute(Const.SESSION_LOGIN_USER, user.get());
+ return "redirect:/menu";
+ }
+
+ @PostMapping("/logout")
+ public String logout(HttpSession session) {
+ session.invalidate();
+ return "redirect:/login";
+ }
}
+
diff --git a/book-rent/src/main/resources/templates/application.html b/book-rent/src/main/resources/templates/application.html
deleted file mode 100644
index de80674..0000000
--- a/book-rent/src/main/resources/templates/application.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
- 書籍貸出申請画面
-
-
-
-
-
- 書籍一覧に戻る
-
-
-
\ No newline at end of file
diff --git a/book-rent/src/main/resources/templates/applicationList.html b/book-rent/src/main/resources/templates/applicationList.html
new file mode 100644
index 0000000..6cacc8b
--- /dev/null
+++ b/book-rent/src/main/resources/templates/applicationList.html
@@ -0,0 +1,34 @@
+
+
+
+
+ 書籍貸出申請一覧(承認待ち)
+
+
+
+
+
+ 書籍貸出申請一覧(承認待ち)
+
+
+
+
承認待ちの申請はありません。
+
+ | 申請ID | 申請者名 | 書籍名 | 申請日 | 貸出日 | 返却予定日 | 操作 |
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+ 承認 |
+
+
+
+
+ メニューに戻る
+
+
+
diff --git a/book-rent/src/main/resources/templates/error.html b/book-rent/src/main/resources/templates/error.html
new file mode 100644
index 0000000..70e22bf
--- /dev/null
+++ b/book-rent/src/main/resources/templates/error.html
@@ -0,0 +1,17 @@
+
+
+
+
+ エラー
+
+
+
+
+ エラー
+
+
+
+
diff --git a/book-rent/src/main/resources/templates/login.html b/book-rent/src/main/resources/templates/login.html
index 6ee30de..dcd376a 100644
--- a/book-rent/src/main/resources/templates/login.html
+++ b/book-rent/src/main/resources/templates/login.html
@@ -2,93 +2,122 @@
-
-
-
-
-
-
-
-
-
-
- ログイン
+
+ ログイン
+
-
-
-
-
-
-
+
+ 書籍貸出管理システム
+
+
-
\ No newline at end of file
+
+