SpringBootで予約キャンセルの機能を実装での画面遷移がうまくいかない。
解決したいこと
SpringBootでキャンセルの機能を実装させたい。
発生している問題・エラー
No static resource reservations/restaurant/2/reservations/cancel.と出ておりコントローラーがみつからない。
該当するソースコード
package com.example.portfolio.controller;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.example.portfolio.entity.Reservation;
import com.example.portfolio.entity.Restaurant;
import com.example.portfolio.entity.User;
import com.example.portfolio.form.ReservationInputForm;
import com.example.portfolio.form.ReservationRegisterForm;
import com.example.portfolio.repository.ReservationRepository;
import com.example.portfolio.repository.RestaurantRepository;
import com.example.portfolio.security.UserDetailsImpl;
import com.example.portfolio.service.ReservationService;
import com.example.portfolio.service.SendMailService;
@Controller
public class ReservationController {
private final ReservationRepository reservationRepository;
private final RestaurantRepository restaurantRepository;
private final ReservationService reservationService;
private final SendMailService sendMailService;
public ReservationController(ReservationRepository reservationRepository,
RestaurantRepository restaurantRepository,
ReservationService reservationService,
SendMailService sendMailService){
this.reservationRepository = reservationRepository;
this.restaurantRepository = restaurantRepository;
this.reservationService = reservationService;
this.sendMailService = sendMailService;
}
<省略>
@PostMapping("/restaurant/{id}/reservations/cancel")
public String cancel(@PathVariable(name = "id") Integer id, RedirectAttributes redirectAttributes) {
Reservation reservation = reservationRepository.getReferenceById(id);
reservationRepository.delete(reservation);
sendMailService.sendMailReservationCancel(reservation);
redirectAttributes.addFlashAttribute("successMessage", "予約をキャンセルしました。");
return "redirect:/reservations";
}
}
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<div th:replace="~{fragment :: meta}"></div>
<div th:replace="~{fragment :: styles}"></div>
<title>予約一覧</title>
</head>
<body>
<div class="nagoyameshi-wrapper">
<div th:replace="~{fragment :: header}"></div>
<main>
<div class="container nagoyameshi-container pb-5">
<div class="row justify-content-center">
<div class="col-xxl-9 col-xl-10 col-lg-11">
<nav class="my-3" style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a th:href="@{/}">トップページ</a></li>
<li class="breadcrumb-item active" aria-current="page">予約一覧</li>
</ol>
</nav>
<h2 class="mb-3 text-center">予約一覧</h2>
<div th:if="${successMessage}" class="alert alert-info">
<span th:text="${successMessage}"></span>
</div>
<div th:if="${param.reserved}" class="alert alert-info">
予約が完了しました。
</div>
<table class="table">
<thead>
<tr>
<th scope="col">店舗名</th>
<th scope="col">日時</th>
<th scope="col">人数</th>
</tr>
</thead>
<tbody>
<tr th:each="reservation : ${reservationPage}">
<td><a th:href="@{/restaurant/__${reservation.getRestaurant().getId()}__}" th:text="${reservation.getRestaurant().getName()}"></a></td>
<td th:text="${reservation.getVisitingTime()}"></td>
<td th:text="${reservation.getNumberOfPeople()}"></td>
<td><a href="#" class="nagoyameshi-link-danger" data-bs-toggle="modal" th:data-bs-target="${'#deleteReservationModal' + reservation.getId()}">キャンセル</a></td>
<div class="modal fade" th:id="${'deleteReservationModal' + reservation.getId()}" tabindex="-1" th:aria-labelledby="${'deleteRestaurantModalLabel' + reservation.getId()}">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" th:id="${'deleteReservationModal' + reservation.getId()}" th:text="${reservation.getRestaurant().getName() + 'の予約をキャンセルしますか?'}"></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="閉じる"></button>
</div>
<div class="modal-footer">
<form method="post"th:action="@{/reservations/restaurant/__${reservation.getId()}__/reservations/cancel}">
<button type="submit" class="btn nagoyameshi-btn-danger text-white shadow-sm">キャンセル</button>
</form>
</div>
</div>
</div>
</div>
</tr>
</tbody>
</table>
<div th:if="${reservationPage.getTotalPages() >1}" class="d-flex justify-content-center">
<nav aria-label="予約一覧ページ">
<ul class="pagination">
<li class="page-item">
<span th:if="${reservationPage.isFirst()}" class="page-link disabled">前</span>
<a th:unless="${reservationPage.isFirst()}" th:href="@{reservations(page = ${reservationPage.getNumber() - 1})}" class="page-link nagoyameshi-page-link">前</a>
</li>
<li th:each="i : ${#numbers.sequence(0, reservationPage.getTotalPages() - 1)}" class="page-item">
<span th:if="${i == reservationPage.getNumber()}" class="page-link active nagoyameshi-active" th:text="${i + 1}"></span>
<a th:unless="${i == reservationPage.getNumber()}" th:href="@{/reservations(page = ${i})}" class="page-link nagoyameshi-page-link" th:text="${i + 1}"></a>
</li>
<li class="page-item">
<span th:if="${reservationPage.isLast()}" class="page-link disabled">次</span>
<a th:unless="${reservationPage.isLast()}" th:href="@{/reservations(page = ${reservationPage.getNumber() + 1})}" class="page-link nagoyameshi-page-link">次</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</main>
<div th:replace="~{fragment :: footer}"></div>
</div>
<div th:replace="~{fragment :: scripts}"></div>
</body>
</html>
自分で試したこと
ここに問題・エラーに対して試したことを記載してください。
似たコードを探してみた。
0