[JAVA] 04. Ich habe mit SpringBoot + Thymeleaf ein Frontend gemacht

Überblick

Dieses Mal werde ich versuchen, ein Frontend (** Thymeleaf **) anstelle der API zu erstellen. Sie fragen sich vielleicht: "Ist es möglich, plötzlich ein Frontend zu erstellen, obwohl es bis zum letzten Mal eine API war?" Aus meiner Sicht ist ** API- und Front-End-Implementierung nicht so unterschiedlich **.

Wenn Sie einige Regeln befolgen (z. B. wo Dateien abgelegt werden sollen), macht Spring Boot das, was Sie wollen. Die wichtigsten Änderungen sind ** Controller-Ebene ** und ** Ansichtsebene wird hinzugefügt **. Mit anderen Worten, die ** Modellschicht (Service, Mapper) kann auf dieselbe Weise wie die API ** konfiguriert und implementiert werden.

Schauen wir uns die Quelle an!

Hauptthema

Ich habe das gleiche Projekt bis zum [letzten Mal] verwendet (https://qiita.com/supreme0110/items/4b7ab92da519c46b8082). Dieses Mal wird es das Frontend sein, also werde ich ein neues Projekt schneiden. (Ich werde das Verfahren weglassen) Als Fälschung fordern wir einfach die Postleitzahlensuch-API wie zuvor an und geben das Ergebnis als HTML zurück. Da der Hauptteil dieser Zeit die Implementierung von View by Thymeleaf ist, werde ich dies hauptsächlich erklären.

1. Fügen Sie eine Abhängigkeit hinzu

Wir werden das bekannte Spring Initializr verwenden. Dieses Mal geben wir "** Web ", " MySQL ", " My Batis ", " Lombok " und " Thymeleaf **" an. 依存追加.png

Klicken Sie nach Auswahl der obigen Option auf ** Projekt generieren **, um ** build.gradle ** in der heruntergeladenen Zip-Datei für Ihr Projekt wiederzugeben. Vergiss ** Reflesh ** nicht.

2. Machen Sie ein Modell

Letztes Mal Kopieren Sie den erstellten GetAddressApiClient und ResponseHeaderInterceptor und bringen Sie sie so, wie sie sind. Vergessen Sie nicht, Ihre Datenklasse mitzubringen.

3. Controller und Ansicht erstellen

3-1. Controller und Ansicht, die den oberen Bildschirm anzeigen

Es ist vorerst der oberste Bildschirm. ** Redirect ** und ** Forward ** sind im Spring Boot verfügbar. Dieses Mal verwende ich Weiterleitungen.

TopController.java


@Controller
public class TopController {
    @GetMapping("/top")
    public String top() {
        return "/top";
    }
    @GetMapping("/")
    public String index() {
        return "redirect:/top"; //Mit dieser Beschreibung/Sie können nach oben umleiten
    }
}

Als nächstes kommt HTML, aber da es nicht ausreicht, es auszudrücken, werde ich es hier weglassen. Verwenden Sie einfach einen einfachen Anker, um zum Suchbildschirm zu springen.

3-2. Erstellen Sie Controller und Ansicht, um Suche und Ergebnisse anzuzeigen

Lassen Sie uns die Validierung sofort implementieren. Zuerst vom Controller.

AddressSearchController.java


@Controller
@RequiredArgsConstructor
public class AddressSearchController {
    private final GetAddressApiClient client;

    @GetMapping("/address/search")
    public String search(@ModelAttribute SearchForm form) { // (1)
        return "/address/search";
    }

    @PostMapping("/address/confirm")
    public String confirm(@ModelAttribute @Valid SearchForm form,
                          BindingResult bindingResult,
                          Model model) {
        if (bindingResult.hasErrors()) { // (2)
            return "/address/search";
        }
        GetAddressApiResponse response = client.request(form.getPostalCode());
        model.addAttribute("addressList", response.getResults()); // (3)
        return "/address/confirm";
    }
}

Lassen Sie uns kurz die wichtigsten Punkte erklären. (1) Das Formular wird aus dem Modell mit dem Argument "@ ModelAttribute" herausgenommen. ** Da die Instanz zum Zeitpunkt der Erstanzeige nicht in Model vorhanden ist, springt Spring new und übergibt dieses Objekt **. Es ist dasselbe, wenn Sie explizit "new" in der Methode und "model.addAttribute ()" angeben, aber wenn Sie dies schreiben, ist dies praktisch, da Sie den Wert mit "forward" erben können! (2) Wenn die in dem bekannten "bindingResult.hasErrors ()" eingegebene Postleitzahl falsch ist, wird der Bildschirm zum Suchbildschirm zurückgesetzt. Die Annotation entspricht übrigens der zuletzt erstellten Postleitzahl. (3) Wenn die eingegebene Postleitzahl korrekt ist, rufen Sie die Adressinformationen über den zuvor erstellten "Client" ab und übergeben Sie den Wert mit dem Namen "addressList" an View.

Als nächstes folgt das HTML des Suchbildschirms.

search.html


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"> <!-- (1) -->
<head>
    <meta charset="UTF-8">
    <title>Sample Search</title>
</head>
<body>
<h2>Suchbildschirm</h2>
<form th:action="@{/address/confirm}" th:method="post" th:object="${searchForm}">
    <label th:for="*{postalCode}">Postleitzahl</label><input th:field="*{postalCode}">
    <span th:if="${#fields.hasErrors('postalCode')}" th:errors="*{postalCode}">error message</span><br/> <!-- (2) -->
    <button type="submit">Suchen nach</button>
</form>
</body>
</html>

Lassen Sie uns zunächst jedes "th" -Tag und jede Beschreibungsmethode erklären, die in diesem HTML-Code erscheinen.

(1) Dies ist eine Beschreibung für die Verwendung des Tags "th" von thymeleaf. Wenn Sie dies nicht angeben, können Sie Thymeleaf nicht verwenden. Vergessen Sie es also nicht. (2). $ {# Fields.hasErrors ('postalCode')} gibt true zurück, wenn eine Validierungsverletzung mit dem Wert von postalCode auftritt. Sie können Fehlermeldungen für ein Feld anzeigen, indem Sie den Feldnamen mit "th: error" angeben. Mit anderen Worten, ** Sie können eine Fehlermeldung ausgeben, wenn mit diesem Satz eine Validierungsverletzung vorliegt **.

Schließlich ist es das HTML des Bestätigungsbildschirms.

confirm.html


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Sample Confirm</title>
</head>
<body>
<h2>Suchergebnisbildschirm</h2>
<table border="1">
    <tr>
        <th>Postleitzahl</th>
        <th>Präfekturcode</th>
        <th>Adresse 1</th>
        <th>Adresse 2</th>
        <th>Adresse 3</th>
        <th>Adresse Kana 1</th>
        <th>Adresse Kana 2</th>
        <th>Adresse Kana 3</th>
    </tr>
    <tr th:each="result : ${addressList}">
        <td th:text="${result.zipcode}"></td>
        <td th:text="${result.prefcode}"></td>
        <td th:text="${result.address1}"></td>
        <td th:text="${result.address2}"></td>
        <td th:text="${result.address3}"></td>
        <td th:text="${result.kana1}"></td>
        <td th:text="${result.kana2}"></td>
        <td th:text="${result.kana3}"></td>
    </tr>
</table>
<a th:href="@{/address/search}">Zurück zum Suchbildschirm</a>
</body>
</html>

Dieses Mal werden die Ergebnisse als Liste zurückgegeben, daher habe ich sie in einer Tabelle ausgegeben. Die auf diesem Bildschirm verwendeten Tags lauten wie folgt.

--th: each… ** Dies ist ein Tag, das Sie häufig verwenden werden. ** Ich denke, es wird einfacher zu verstehen sein, wenn Sie sich die erweiterte Java-Anweisung vorstellen können. Die Werte werden in der Reihenfolge von "$ {addressList}" abgerufen, und die Werte können mit dem Namen "result" verwendet werden. --th: text… ** Dies ist ein Tag, das Sie häufig verwenden werden. ** Wie der Name schon sagt, wird es verwendet, wenn Sie es auf dem Bildschirm anzeigen möchten, und der Wert wird nach dem Rendern auf " </ td>" erweitert. Es ist mit XSS kompatibel und maskiert Metazeichen, sodass Sie es sicher verwenden können.

Ist es so ein Ort? Zum Schluss lasst es uns vom Browser aus treffen! !!

4. Versuchen Sie es zu treffen

4-1. Oberer Bildschirm

BootRun, um auf http: // localhost: 8080 / zuzugreifen. トップ画面.png Klicken Sie auf ** Nach Postleitzahl suchen **, um zum Suchbildschirm zu gelangen.

4-2. Suchbildschirm

検索画面.png

Die HTML-Quelle nach dem Rendern sieht folgendermaßen aus. 検索画面_html.png th: field wird erweitert, ** id und name sind Variablennamen und value ist leer **. Geben Sie nun den richtigen Wert ein und klicken Sie auf ** Suchen **.

4-3. Ergebnisbildschirm

Zuallererst, wenn das Ergebnis singulär ist. 結果画面.png

Dann, wenn es mehrere Ergebnisse gibt. 結果画面_複数.png th: each funktioniert einwandfrei und Sie können alle sehen, auch wenn es mehrere gibt.

Schauen wir uns zum Schluss den Fall eines Validierungsfehlers an.

4-4. Validierungsfehler

検索画面_不正値.png Wenn Sie einen ungültigen Wert eingeben und auf ** Suchen ** klicken ...

検索画面_不正値_エラー.png Sie haben die Fehlermeldung erfolgreich angezeigt. Diese Nachricht ist übrigens eine feste Zeichenfolge, die in der Standardeinstellung "ZipCode.message" geschrieben ist.

Schließlich

Es war wahnsinnig einfach, aber es war eine Front-End-Implementierung. ** Thymeleaf ist tief und die Tags und Beschreibungsmethoden, die ich berühre, sind nur die Spitze des Eisbergs. ** ** ** Sie können immer mehr tun, also probieren Sie es aus!

Ich denke, dass danach CSS und Javascript benötigt werden, aber kürzlich hatte ich die Gelegenheit, ** semantic ui ** zu berühren. Es kann mit CDN verwendet werden und wird durch Angabe des Klassennamens dekoriert. Bei Interesse können Sie sich gerne an uns wenden!

Danke, dass du bis zum Ende zugesehen hast! !!

Recommended Posts

04. Ich habe mit SpringBoot + Thymeleaf ein Frontend gemacht
Ich habe mit Swing eine GUI erstellt
Ich habe mit Ruby einen riskanten Würfel gemacht
Ich habe eine Janken App mit Kotlin gemacht
Ich habe eine Janken App mit Android gemacht
Ich habe Mosaikkunst mit Pokemon-Bildern gemacht
Ich habe einen LINE Bot mit Rails + Heroku gemacht
Ich habe mit Ruby On Rails ein Portfolio erstellt
[Ruby] Ich habe einen Crawler mit Anemone und Nokogiri gemacht.
Ich habe eine Chat-App erstellt.
Ich habe einen CRUD-Test mit SpringBoot + MyBatis + DBUnit geschrieben (Teil 1)
Ich habe eine Entwicklungsumgebung mit Rails6 + Docker + PostgreSQL + Materialise erstellt.
Erstellen Sie eine einfache CRUD mit SpringBoot + JPA + Thymeleaf ~ ~ Validierung hinzufügen ~
Ich habe ein Plug-In erstellt, das Jextract mit Gradle-Aufgaben ausführt
Erstellen Sie mit SpringBoot + JPA + Thymeleaf ein einfaches CRUD ~ ~ Hallo Welt ~
Ich habe einen MOD erstellt, der sofort ein Fahrzeug mit Minecraft anruft
Erstellen Sie eine einfache CRUD mit SpringBoot + JPA + Thymeleaf ⑤ ~ Common template ~
Zeichnen Sie den Bildschirm mit Thymeleaf in SpringBoot
Implementieren Sie einen Textlink mit Springboot + Thymeleaf
Ich habe eine shopify App @java erstellt
Ich habe eine einfache Empfehlungsfunktion erstellt.
Ich habe eine passende App erstellt (Android App)
Ich habe ein Tool zur Generierung von package.xml erstellt.
[Android] Ich habe eine Schrittzähler-App erstellt.
Ich habe mit JD-Core eine Befehlszeilenschnittstelle mit dem WinMerge Plugin erstellt
[Rails] Ich habe eine einfache Kalender-Mini-App mit benutzerdefinierten Spezifikationen erstellt.
Erstellen Sie eine einfache CRUD mit SpringBoot + JPA + Thymeleaf ④ ~ Fehlermeldung anpassen ~
Ich habe ein einfaches Suchformular mit Spring Boot + GitHub Search API erstellt.
[Ruby] Ich habe einen einfachen Ping-Client erstellt
Erstellen Sie eine einfache CRUD mit SpringBoot + JPA + Thymeleaf ② ~ Bildschirm- und Funktionserstellung ~
Ich habe einen Öko-Server mit Scala gemacht
Ich habe versucht, OnlineConverter mit SpringBoot + JODConverter zu verwenden
Ich habe versucht, ein wenig mit BottomNavigationView zu spielen ①
Ich habe ein Plug-In für IntelliJ IDEA erstellt
Ich habe eine Taschenrechner-App für Android erstellt
Deserialisieren Sie XML mit Spring-Boot in eine Sammlung
Ich habe ein neues Java-Bereitstellungstool erstellt
[LINE BOT] Ich habe einen Ramen BOT mit Java (Maven) + Heroku + Spring Boot (1) gemacht.
Ich habe mit Vue.js eine Seite erstellt, die Informationen zur Zuckereinschränkung zusammenfasst
Lerne Java mit Progate → Ich werde es erklären, weil ich selbst ein einfaches Spiel gemacht habe
Ich habe ein Diff-Tool für Java-Dateien erstellt
Ich habe ein Programm zur Beurteilung von Primzahlen in Java erstellt
Ich habe mit Ruby einen Blackjack gemacht (ich habe versucht, Minitest zu verwenden)
Ich habe ein Janken-Spiel in Java (CLI) gemacht.
Ich habe eine Viewer-App erstellt, die PDF anzeigt
Ich habe einen Docker-Container erstellt, um Maven auszuführen
Ich habe eine Ruby-Erweiterungsbibliothek in C erstellt
[Rails] Ich habe eine Entwurfsfunktion mit enum erstellt
Ich habe Code Pipeline mit AWS CDK erstellt.
Zeigen Sie eine einfache Hallo Welt mit SpringBoot + IntelliJ
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe StringUtils.isBlank gemacht
Ich habe versucht, eine mit antikem Middleman erstellte Seite in Azure Static Web Apps bereitzustellen
Ich habe mit der Lautstärketaste mit der Android-App ein Sperrmuster erstellt. Fragment Edition
Ich habe eine Funktion zum Registrieren von Bildern bei der API in Spring Framework erstellt. Teil 1 (API Edition)
Ich habe ein Docker-Image für die japanische Version von SDAPS erstellt