・ Lernen von Java / Spring Boot / Thymeleaf ・ Ich möchte eine einfache Webanwendung zum Üben erstellen
Erstellen Sie eine einfache Web-App, mit der Sie Kunden verwalten können (Registrieren / Aktualisieren / Löschen / Auflisten). Zertifizierung / Autorisierung / Komponententest wird weggelassen, da es viel sein wird. Es kann jedoch besser sein, den Komponententest hinzuzufügen, wenn Zeit vorhanden ist.
Das fertige Bild ist wie folgt.
Wenn Sie zuerst das fertige Produkt sehen möchten, bitte.
Die Quelle ist hier.
Das, was funktioniert, ist hier.
Es wird davon ausgegangen, dass die Entwicklungsumgebung und PostgreSQL installiert wurden. Wenn Sie es nicht installiert haben, folgen Sie bitte dem Link unten.
Die Gesamtkonfiguration der diesmal erstellten Webanwendung lautet wie folgt.
Grob gesagt ...
Da Entwicklung das Hauptthema ist, ist funktionales Design einfach zu schreiben.
No | Künstlername | Erläuterung |
---|---|---|
1 | der obere Bildschirm | Der Bildschirm, der als Eingang zu jedem Bildschirm dient. |
2 | Neuer Registrierungsbildschirm | Ein Bildschirm zum Neuregistrieren von Kundeninformationen. |
3 | Bildschirm aktualisieren | Ein Bildschirm zum Ändern von Kundeninformationen. |
4 | Listenbildschirm | Ein Bildschirm zum Anzeigen und Löschen von Kundeninformationen in einer Liste. |
Gemäß [2. Ziel](# 2-Ziel).
Ich denke, Sie können es verstehen, also habe ich es weggelassen.
No | URL | HTTP-Methode | Erläuterung |
---|---|---|---|
1 | / | GET | der obere Bildschirm |
2 | /customers | GET | Listenbildschirm |
3 | /customers/create | GET | Neuer Registrierungsbildschirm |
4 | /customers/create | POST | Neue Registrierungsausführung |
5 | /customers/{id}/update | GET | Bildschirm aktualisieren |
6 | /customers/{id}/update | POST | Aktualisieren Sie die Ausführung |
7 | /customers/{id}/delete | GET | Ausführung löschen |
Entworfen mit Bezug auf hier.
No | Tabellenname | Erläuterung |
---|---|---|
1 | customer | Kundeninformationen verwalten. |
No | Spaltenname | PK | Nicht Null | Erläuterung |
---|---|---|---|---|
1 | id | ○ | ○ | Kundennummer. Automatische Nummerierung nacheinander. |
2 | name | ○ | Kundenname. |
Kommen wir nun zur Entwicklung des Hauptthemas.
Laden Sie die Vorlage von der offiziellen Spring-Website herunter und entwickeln Sie sie weiter. Die Tabelle wird automatisch von Model durch die Funktion von Spring JPA generiert.
Erstellen Sie eine Vorlage für Ihr Web-App-Projekt. Es kann einfach von Spring Initializr heruntergeladen werden. Sie können es herunterladen, indem Sie Folgendes eingeben und auf die Schaltfläche "Generieren" klicken.
Stellen Sie die zu verwendenden externen Bibliotheken ein.
Sie können dasselbe über das Eclipse-Menü tun. Insbesondere sind dies "Datei", "Neu", "Andere", "Spring Boot" und "Spring Starter Project".
Importieren Sie die heruntergeladene Vorlage in Eclipse. Das spezifische Verfahren ist wie folgt.
Es wird beim Import automatisch gemäß den Abhängigkeiten in build.gradle erstellt. Externe Bibliotheken werden heruntergeladen.
Einige externe Bibliotheken sind in Spring Initializr nicht enthalten. Insbesondere ist die Bootstrap-Java-Bibliothek nicht enthalten. Öffnen Sie die Datei build.gradle in Eclipse und fügen Sie sie wie folgt hinzu.
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.webjars:jquery:3.3.1' //hinzufügen
implementation 'org.webjars:bootstrap:4.3.1' //hinzufügen
implementation 'org.webjars:font-awesome:5.13.0' //hinzufügen
//Kürzung. Die Vollversion ist https://github.com/tk230to/tksystem
Suchen Sie nach diesen Bibliotheken im Maven Repository (https://mvnrepository.com/).
Erstellen Sie jede Klasse und Konfigurationsdatei.
Erstellen Sie eine Modell- / Ansichts- / Controller- / Konfigurationsdatei. Was war diese Datei? In diesem Fall lesen Sie bitte noch einmal [5.2 Konfiguration](# 52-Konfiguration).
Erstellen Sie eine Klasse, die der Kundentabelle entspricht (# 63-db-Design). Klassenname = Tabellenname, Feldname = Spaltenname.
Customer.java
package com.example.tksystem.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.validation.constraints.NotBlank;
import lombok.Data;
/**
*Kundenklasse.
*/
@Entity
@Data
public class Customer {
/**Sequenzname*/
private static final String SEQUENCE_NAME = "customer_id_seq";
/** ID */
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SEQUENCE_NAME)
@SequenceGenerator(name = SEQUENCE_NAME, sequenceName = SEQUENCE_NAME, allocationSize = 1)
private Long id;
/**Name*/
@NotBlank
private String name;
}
Erstellen Sie eine Klasse, um CRUD-Operationen für die Kundentabelle auszuführen. Es erbt nur von JpaRepository.
CustomerRepository.java
package com.example.tksystem.model;
import org.springframework.data.jpa.repository.JpaRepository;
/**
*Kunden-Repository-Klasse.
*/
public interface CustomerRepository extends JpaRepository<Customer, Long> {
}
Die folgenden Methoden (Auszüge) stehen zur Verfügung.
Erstellen Sie für jeden Bildschirm eine HTML-Vorlage. Da die Navigationsleiste oben allen Bildschirmen gemeinsam ist, wird sie als gemeinsames Layout verwendet.
layout.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head(title)">
<title th:text="'Kundenmanagement- ' + ${title}">tksystem</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" th:href="@{/webjars/bootstrap/4.3.1/css/bootstrap.min.css}" />
<link rel="stylesheet" th:href="@{/webjars/font-awesome/5.13.0/css/all.min.css}" />
<script th:src="@{/webjars/jquery/3.3.1/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/4.3.1/js/bootstrap.min.js}"></script>
</head>
<body>
<nav class="navbar navbar-dark bg-dark navbar-expand-sm mb-3" th:fragment="navbar">
<a class="navbar-brand" href="/">Kundenmanagement</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#Navbar" aria-controls="Navbar" aria-expanded="false" aria-label="Navigation wechseln">
<span class="navbar-toggler-icon"></span>
</button>
<div id="Navbar" class="collapse navbar-collapse">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" th:href="@{/customers/create/}">
<i class="fas fa-plus fa-lg" aria-hidden=”true”></i>Anmelden
</a>
</li>
<li class="nav-item">
<a class="nav-link" th:href="@{/customers/}">
<i class="fas fa-list fa-lg" aria-hidden=”true”></i>Aufführen
</a>
</li>
</ul>
</div>
</nav>
</body>
</html>
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/layout :: head('Home')">
</head>
<body>
<div th:replace="fragments/layout :: navbar"></div>
<div class="container-fluid">
<h5>Speisekarte</h5>
<hr>
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<a class="nav-link" th:href="@{/customers/create}">
<i class="fas fa-plus fa-lg" aria-hidden=”true”></i>Anmelden
</a>
</h5>
<p class="card-text">Registrieren Sie einen neuen Kunden.</p>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<a class="nav-link" th:href="@{/customers/}">
<i class="fas fa-list fa-lg" aria-hidden=”true”></i>Aufführen
</a>
</h5>
<p class="card-text">Zeigen Sie eine Kundenliste an.</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
create.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/layout :: head('Anmelden')">
</head>
<body>
<div th:replace="fragments/layout :: navbar"></div>
<div class="container-fluid">
<h5>Anmelden</h5>
<hr>
<div class="row">
<div class="col-sm-12">
<form action="#" th:action="@{/customers/create/}" th:object="${customer}" method="post">
<div class="form-group">
<label for="name">Name<span class="badge badge-danger">Verpflichtend</span></label>
<input type="text" id="name" class="form-control" placeholder="(Beispiel)Yamada Taro" th:field="*{name}" />
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" style="color: red"></span>
</div>
<button type="submit" class="btn btn-primary">Bestätigen</button>
</form>
</div>
</div>
</div>
</body>
</html>
Es ist fast das gleiche wie der Registrierungsbildschirm. Das fertige Produkt ist hier
list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/layout :: head('Aufführen')">
</head>
<body>
<div th:replace="fragments/layout :: navbar"></div>
<div class="container-fluid">
<h5>Aufführen</h5>
<hr>
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th width="10%">ID</th>
<th width="80%">Name</th>
<th width="10%">Löschen</th>
</tr>
</thead>
<tbody>
<tr th:each="customer:${customer}">
<td th:text="${customer.id}"></td>
<td>
<a th:text="${customer.name}" th:href="@{/customers/{id}/update/(id=${customer.id})}">
</a>
</td>
<td>
<a th:href="@{/customers/{id}/delete/(id=${customer.id})}" onClick="return window.confirm('Sind Sie sicher, dass Sie löschen möchten?')">
<i class="far fa-trash-alt fa-lg" aria-hidden=”true”></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Erstellen Sie eine Klasse, um Anforderungen auf dem oberen Bildschirm zu verarbeiten.
IndexController.java
package com.example.tksystem.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*Index Screen Controller Klasse.
*/
@Controller
@RequestMapping("/")
public class IndexController {
/**
*Indexbildschirm
*
* @param Modell Modell
* @Übergangsziel zurückgeben
*/
@RequestMapping("index")
public String index(Model model) {
return "index";
}
}
Erstellen Sie eine Klasse, um Anforderungen auf dem Kundenbildschirm zu bearbeiten (neuer Registrierungs- / Aktualisierungs- / Listenbildschirm).
CustomerController.java
package com.example.tksystem.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
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.bind.annotation.RequestMapping;
import com.example.tksystem.model.Customer;
import com.example.tksystem.model.CustomerRepository;
/**
*Kundenbildschirm-Controller-Klasse.
*/
@Controller
@RequestMapping("/customers")
public class CustomerController {
/**Anmeldung/aktualisieren/Leiten Sie die Ziel-URL nach Abschluss des Löschvorgangs um*/
private static final String REDIRECT_URL = "redirect:/customers/";
/**HTML-Pfad*/
private static final String PATH_LIST = "customer/list";
private static final String PATH_CREATE = "customer/create";
private static final String PATH_UPDATE = "customer/update";
/**Modellattributname*/
private static final String MODEL_ATTRIBUTE_NAME = "customer";
/**Kunden-Repository*/
@Autowired
private CustomerRepository customerRepository;
/**
*Zeigen Sie den Listenbildschirm an.
*
* @param Modell Modell
* @Übergangsziel zurückgeben
*/
@GetMapping(value = "/")
public String list(Model model) {
model.addAttribute(MODEL_ATTRIBUTE_NAME, customerRepository.findAll(Sort.by("id")));
return PATH_LIST;
}
/**
*Zeigen Sie den Registrierungsbildschirm an.
*
* @param Modell Modell
* @Übergangsziel zurückgeben
*/
@GetMapping(value = "/create")
public String create(Model model) {
model.addAttribute(MODEL_ATTRIBUTE_NAME, new Customer());
return PATH_CREATE;
}
/**
*Registrierung durchführen.
*
* @param Kunde Eingabewert des Kundenbildschirms
* @param result Eingabeprüfungsergebnis
* @Übergangsziel zurückgeben
*/
@PostMapping(value = "/create")
public String create(@Validated @ModelAttribute(MODEL_ATTRIBUTE_NAME) Customer customer,
BindingResult result) {
if (result.hasErrors()) {
return PATH_CREATE;
}
customerRepository.save(customer);
return REDIRECT_URL;
}
/**
*Zeigen Sie den Aktualisierungsbildschirm an.
*
* @param id Kunden-ID
* @param Modell Modell
* @Übergangsziel zurückgeben
*/
@GetMapping(value = "/{id}/update")
public String update(@PathVariable("id") Long id, Model model) {
model.addAttribute(MODEL_ATTRIBUTE_NAME, customerRepository.getOne(id));
return PATH_UPDATE;
}
/**
*Führen Sie das Update durch.
*
* @param Kunde Eingabewert des Kundenbildschirms
* @param result Eingabeprüfungsergebnis
* @Übergangsziel zurückgeben
*/
@PostMapping(value = "/{id}/update")
public String update(@Validated @ModelAttribute(MODEL_ATTRIBUTE_NAME) Customer customer,
BindingResult result) {
if (result.hasErrors()) {
return PATH_UPDATE;
}
customerRepository.save(customer);
return REDIRECT_URL;
}
/**
*Löschen durchführen.
*
* @param id Kunden-ID
* @Übergangsziel zurückgeben
*/
@GetMapping(value = "/{id}/delete")
public String list(@PathVariable("id") Long id) {
customerRepository.deleteById(id);
return REDIRECT_URL;
}
}
application.yml Diese Datei wird zum Festlegen von DB-Verbindungsinformationen usw. verwendet. URL / Benutzername / Passwort ist die Standardeinstellung für PostgreSQL. Wenn es vom Standard abweicht, ändern Sie es.
application.yml
spring:
datasource:
#Postgres IP-Adresse/Port-Nummer/DB-Name
url: jdbc:postgresql://localhost:5432/postgres
#Postgres Benutzername
username: postgres
#Postgres Passwort
password: postgres
#Postgres JDBC-Treiber
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
# @Löschen Sie immer die Tabelle, die der Entität entspricht&erstellen.
ddl-auto: create-drop
hibernate.properties Diese Einstellung vermeidet Ausnahmen, die in PostgreSQL x Spring JPA auftreten. Ohne es gibt es kein Problem im Betrieb, aber es ist unangenehm, jedes Mal eine Ausnahme zu erhalten, daher ist es besser, sie einzustellen. Details zur Ausnahme hier
hibernate.properties
# PgConnection.createClob()Vermeiden Sie Methodenwarnungen
hibernate.jdbc.lob.non_contextual_creation = true
ValidationMessages.properties Die Nachrichtendefinition der Fehlermeldung für die Eingabeprüfung. Ich werde meine eigene machen, da die japanische Nachricht noch nicht bereitgestellt wurde. Die Pull-Anfrage wurde unter hier erfasst, daher denke ich, dass sie bald bereitgestellt wird.
ValidationMessages.properties
javax.validation.constraints.AssertFalse.message =Bitte auf false setzen
javax.validation.constraints.AssertTrue.message =Bitte auf true setzen
javax.validation.constraints.DecimalMax.message = {value} ${inclusive == true ? 'Bitte stellen Sie die folgenden Werte ein' : 'Bitte verkleinern Sie es'}
javax.validation.constraints.DecimalMin.message = {value} ${inclusive == true ? 'Bitte stellen Sie den obigen Wert ein' : 'Bitte stellen Sie einen größeren Wert ein'}
javax.validation.constraints.Digits.message =Der Wert sollte im folgenden Bereich liegen(<ganze Zahl{integer}Ziffer>.<Nach dem Dezimalpunkt{fraction}Ziffer>)
javax.validation.constraints.Email.message =Bitte formatieren Sie es korrekt als E-Mail-Adresse
javax.validation.constraints.Future.message =Bitte setzen Sie einen zukünftigen Termin
javax.validation.constraints.FutureOrPresent.message =Auf aktuelles oder zukünftiges Datum einstellen
javax.validation.constraints.Max.message = {value}Bitte stellen Sie die folgenden Werte ein
javax.validation.constraints.Min.message = {value}Bitte stellen Sie den obigen Wert ein
javax.validation.constraints.Negative.message =Muss kleiner als 0 sein
javax.validation.constraints.NegativeOrZero.message =Bitte setzen Sie den Wert auf 0 oder weniger
javax.validation.constraints.NotBlank.message =Leerzeichen sind nicht erlaubt
javax.validation.constraints.NotEmpty.message =Leere Elemente sind nicht zulässig
javax.validation.constraints.NotNull.message =null ist nicht erlaubt
javax.validation.constraints.Null.message =Bitte machen Sie es null
javax.validation.constraints.Past.message =Bitte setzen Sie auf ein vergangenes Datum
javax.validation.constraints.PastOrPresent.message =Bitte stellen Sie das aktuelle oder vergangene Datum ein
javax.validation.constraints.Pattern.message =Reguläre Ausdrücke"{regexp}"Bitte passen Sie zu
javax.validation.constraints.Positive.message =Muss größer als 0 sein
javax.validation.constraints.PositiveOrZero.message =Muss größer oder gleich 0 sein
javax.validation.constraints.Size.message = {min}Von{max}Bitte machen Sie die Größe zwischen
WebConfig Nehmen Sie Einstellungen vor, um die oben genannten ValidationMessages.properties zu verwenden. Weitere Informationen finden Sie unter hier.
WebConfig.java
package com.example.tksystem;
import java.nio.charset.StandardCharsets;
import org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
*Webkonfigurationsklasse.
*
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public Validator getValidator() {
// ValidationMessages.Eigenschaften zu UTF-Ermöglicht das Einstellen mit 8.
ReloadableResourceBundleMessageSource messageSource =
new ReloadableResourceBundleMessageSource();
messageSource.setBasename(AbstractMessageInterpolator.USER_VALIDATION_MESSAGES);
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
}
Nachdem alle Dateien vollständig sind, führen Sie das Projekt in Eclipse aus. Das Verfahren besteht darin, ein Projekt auszuwählen, mit der rechten Maustaste zu klicken, auszuführen und eine Spring Boot-Anwendung zu erstellen.
Durch Setzen von ddl-auto set in application.yml Die Tabelle wird automatisch gemäß der erstellten Entitätsklasse generiert.
Bitte greifen Sie auf [http: // localhost: 8080](http: // localhost: 8080) zu und überprüfen Sie den Vorgang. Wenn es wie [2. Ziel](# 2-Ziel) funktioniert, ist es erfolgreich.
Danke für deine harte Arbeit.