我一直在开发一个带有前端和后端的简单项目,用于管理大学 IT 门票。在使用 Spring 和 MySQL 数据库实现了不同的方法(并且所有方法都运行良好)之后,我们需要使用 thymeleaf 来实现,但由于某种原因,它既不保存也不显示信息。我已经检查过,application.properties 中数据库的路径和密码是正确的,并且所有依赖项都在 pom.xml 中。这是代码:
票务控制器:
package ch.supsi.webapp.web.controller;
import ch.supsi.webapp.web.model.Status;
import ch.supsi.webapp.web.model.Ticket;
import ch.supsi.webapp.web.repository.TicketRepository;
import ch.supsi.webapp.web.service.TicketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
@Controller
public class TicketController {
TicketService service;
public TicketController(TicketRepository repository,TicketService service) {
this.service=service;
}
@GetMapping("/index")
public String index(Model model){
model.addAttribute("tickets",service.list());
//model.addAttribute("openTickets", service.findLast5ByStatus(Status.OPEN));
//model.addAttribute("closedTickets", service.findLast5ByStatus(Status.CLOSED));
return "index";
}
@PostMapping("/ticket/new")
public String newPost(Model model){
model.addAttribute("ticket", new Ticket());
model.addAttribute("isNew", true);
model.addAttribute("authors", service.getAuthors());
return "redirect:/";
}
@PostMapping("/ticket/new")
public String post(Ticket ticket) throws IOException {
service.save(ticket);
return "redirect:/";
}
}
票务服务
package ch.supsi.webapp.web.service;
import ch.supsi.webapp.web.model.Status;
import ch.supsi.webapp.web.model.Ticket;
import ch.supsi.webapp.web.repository.TicketRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ch.supsi.webapp.web.model.Author;
import ch.supsi.webapp.web.repository.AuthorRepository;
import java.util.List;
import java.util.Optional;
@Service
public class TicketService {
private final TicketRepository repository;
private final AuthorRepository authorRepository;
public TicketService(TicketRepository ticketRepository, AuthorRepository authorRepository) {
this.repository = ticketRepository;
this.authorRepository = authorRepository;
}
public void save(Ticket ticket) {
repository.save(ticket);
}
public void remove(long id) {
repository.deleteById((int) id);
}
public Optional<Ticket> read(long id){
return repository.findById((int) id);
}
public List<Ticket> list() {
return (List<Ticket>) repository.findAll();
}
public void update(long id , Ticket ticket){
Optional<Ticket> optionalTicket = repository.findById((int) id);
// Optional<Ticket> optionalAuthor = repository.findById(ticket.getAuthor());
Ticket existingTicket = optionalTicket.get();
//existingTicket.setAuthor(ticket.getAuthor());
existingTicket.setTitle(ticket.getTitle());
existingTicket.setDescription(ticket.getDescription());
repository.save(existingTicket);
}
public List<Ticket> findLast5ByStatus(Status ticketStatus){
return repository.findByStatusOrderByDateDesc(ticketStatus);
}
public List<Author> getAuthors() {
return (List<Author>) authorRepository.findAll();}
public boolean exists(int id) {
return repository.existsById(id);
}
}
票证存储库
package ch.supsi.webapp.web.repository;
import ch.supsi.webapp.web.model.Status;
import ch.supsi.webapp.web.model.Ticket;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface TicketRepository extends CrudRepository<Ticket, Integer>
{
List<Ticket> findByStatusOrderByDateDesc(Status ticketStatus);
//public Ticket findTicket(long id);
//public void setChanges(Ticket ticket);
}
/ticket/new.html
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<header>
<img alt="SUPSI" height="32" src="https://www.supsi.ch/o/supsi-theme/images/supsi-logo.svg" width="117">
<h1>SUPSI Tickets</h1>
</header>
<nav>
<hr>
<a th:href="@{/static}">Home</a> |
<a>New ticket</a> |
<hr>
</nav>
<form method="post" th:action="@{/ticket/new}" th:object="${ch.supsi.webapp.web.model.Ticket}">
<fieldset>
<legend>New ticket</legend>
<div>
<label >Title:
<input th:field="*{title}" type="text">
</label>
</div>
<div>
<label for="author">Author:</label>
<input id="author" class="form-select" th:field="*{author}">
</div>
<div >
<label for="status">Status:</label>
<select id="status" th:field="*{status}">
<option th:each="status : ${T(ch.supsi.webapp.web.model.Status).values()}" th:value="${status.values()}" th:text="${status.values()}"></option>
</select>
</div>
<div>
<label for="type">Type:</label>
<select id="type" th:field="*{type}">
<option th:each="type : ${T(ch.supsi.webapp.web.model.Type).values}" th:value="${type}" th:text="${type}">Bug</option>
</select>
</div>
<div>
<label >Description:</label>
<textarea th:field="*{description}"></textarea>
</div>
</fieldset>
<input type="submit" th:value="${isNew} ? 'Create ticket':'Update ticket'">
</form>
<footer>
<hr>
<small>TICKETS Copyleft CC-by
<time datetime="2022">2022</time>
by L:S</small>
<hr>
</footer>
</body>
</html>
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<title> This is PP5 page</title>
</head>
<body>
<nav>
<ul>
<div class="item"> <a href="index.html" >Home</a></div>
<div class="item"><a th:href="@{/ticket/new}" href="ticket/new.html" >New Ticket </a></div>
<div class="item"><a href="ticket1Details.html">Ticket 1 details</a></div>
</ul>
</nav>
<header >
<h2>Welcome ! </h2>
</header>
<main>
<div> <h2> Ticket management system </h2></div>
<section>
<h2>Open tickets</h2>
<article th:each="ticket : ${tickets}">
<span th:text="${#dates.format(ticket.date, 'dd.MM.yyyy HH:mm')}"></span>
<h3 th:text="${ticket.getTitle()}">Il primo ticket</h3>
<a th:href="@{'/ticket/'+${ticket.getId()}}">view</a>
<a th:href="@{'/ticket/'+${ticket.getId()}+'/edit'}">edit</a>
</article>
<article th:if="${#lists.isEmpty(openTickets)}">There's no ticket. Yippee!</article>
</section>
<aside rel="stylesheet" href="style.css">
<p>This is PP5 sidebar</p>
</aside>
</main>
<footer rel="stylesheet" href="style.css">
<h3> This is the footer </h3>
<p> Copyleft CC-by 2023 by Patricia </p>
</footer>
</body>
</html>
当您多次映射资源“/ticket/new”时,此代码将不会运行,因此 Spring 不知道要调用哪个方法。