[JAVA] Die Bedeutung von th: field in Thymeleaf und der Mechanismus der Übergabe von Werten von Spring Framework

Einführung

In Thymeleaf habe ich th: field oft verwendet, als würde ich mich an einen der Idioten erinnern, aber ich habe das Gefühl, dass ich kürzlich dieser Ebene des Verstehens entkommen bin, deshalb möchte ich den Inhalt zusammenfassen.

Als Übersicht wird der Schwerpunkt auf der Form-Klasse liegen, die für die Übergabe von Werten im Spring Framework verantwortlich ist. Letztendlich wird der Wert ohne Verwendung der Form-Klasse übergeben.

Das Ziel ist wie folgt.

Es ist eine Geschichte, wie man versteht, also ** ist es nicht sehr praktisch. ** ** **

Annahme

Sie benötigen ein Webprojekt, das mit dem Spring Framework erstellt wurde. Die Template-Engine basiert auf Thymeleaf.

Allgemeine Umsetzung

Betrachten wir zunächst eine allgemeine Implementierung mit Form. Von hier aus können Sie den Code optimieren und schließlich die Formularklasse löschen.

BookForm.java

public class BookForm {

	private String title;
	private int price;
	private String summary;
	//	Getter,Setter weggelassen
}

SampleController.java

@Controller
public class SampleController {

	//Eingabebildschirm
	@GetMapping("/input")
	public String input(@ModelAttribute("bookForm") BookForm bookForm) {
		return "input";
	}

	//Buchinformationsbildschirm
	@PostMapping("/bookinfo")
	public String toBookInfo(@ModelAttribute("bookForm") BookForm bookForm) {
		return "bookinfo";
	}
}

input.html

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>Implementierung mit der Form-Klasse</h3>
	<form th:action="@{/bookinfo}" method="post" th:object="${bookForm}">
	<label>Titel</label><br>
	<input type="text" th:field="*{title}"><br>
	<label>Preis</label><br>
	<input type="text" th:field="*{price}"><br>
	<label>Überblick</label><br>
	<input type="text" th:field="*{summary}"><br>
	<button>Senden</button>
	</form>

bookinfo.html

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>Implementierung mit der Form-Klasse</h3>
	<div th:object="${bookForm}">
	<label>Titel</label><br>
	<span th:text="*{title}"></span><br>
	<label>Preis</label><br>
	<span th:text="*{price}"></span><br>
	<label>Memo</label><br>
	<span th:text="*{summary}"></span><br>
	</div>

Der Eingabewert wird ausgegeben, was eine sehr einfache Implementierung ist.

スクリーンショット 2018-11-06 22.23.08.png スクリーンショット 2018-11-06 22.28.54.png

Löschen Sie das Feld th: und das Objekt th: in input.html

Ziehen Sie zunächst in Betracht, th: field und th: object aus input.html zu entfernen. Um die Identität von "th: field" und "th: object" zu ermitteln, verwenden Sie die Entwicklertools von Chrome, um zu sehen, wie die in Thymeleaf geschriebene Datei input.html aussieht. Machen wir das.

スクリーンショット 2018-11-06 22.49.40.png

Das Objekt th: verschwindet aus dem Formular-Tag und das Textfeld zur Eingabe des im Feld th: beschriebenen Titels wird zu "<input type =" text "id =" title "name =" title "value>" Sie können sehen, dass es gibt. Einfach ausgedrückt ist es möglich, th: field und th: object zu löschen, indem genau so geschrieben wird, wie es in den Entwicklertools angezeigt wird. Wenn Sie nur die erforderliche Beschreibung schreiben, lautet diese wie folgt.

input.html

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>th:Implementierung mit gelöschtem Objekt</h3>
	<form th:action="@{/bookinfo}" method="post">
	<label>Titel</label><br>
	<input type="text" name="title"><br>
	<label>Preis</label><br>
	<input type="text" name="price"><br>
	<label>Überblick</label><br>
	<input type="text" name="summary"><br>
	<button>Senden</button>
	</form>

Selbst mit dieser HTML-Beschreibung kann der in [Allgemeine Implementierung](# Allgemeine Implementierung) gezeigte Prozess der "Ausgabe des Eingabewerts" realisiert werden.

Die Tatsache, dass die Beschreibung des Objekts th: weg ist, bedeutet, dass die Form-Klasse der Eingabemethode von SampleController.java ebenfalls gelöscht werden kann.

	//Eingabebildschirm
	@GetMapping("/input")
	public String input() {
		return "input";
	}

Die wichtigste Sache ist ** Wenn Sie im neme-Attribut des Eingabe-Tags einen Feldnamen für eine Formularklasse angeben, wird der eingegebene Wert in diesem Feld gespeichert. ** darüber.

Fast alles, was ich in diesem Artikel sagen möchte, liegt in dieser Tatsache. (Das Obige ist nicht genau die richtige Erklärung für das Verhalten von th: field. Einzelheiten finden Sie unter Formularbindungsfunktion durch th: field und th: object (Eingabetag / grundlegendes Eingabesystem). Ich würde mich freuen, wenn Sie sich auf Folgendes beziehen könnten: //casual-tech-note.hatenablog.com/entry/2018/10/10/224250)

Formularklassen tauschen

Mit dem oben genannten Mechanismus können Sie Folgendes tun: Angenommen, Sie haben die folgende Formularklasse namens MovieForm, die sich von BookForm unterscheidet.

MovieForm.java

public class MovieForm {

	private String title;
	private String summary;
	//	Getter,Setter weggelassen
}

(Entschuldigen Sie das unnatürliche Beispiel.) Angenommen, Sie möchten die Buchinformationen, die mit dieser MovieForm-Klasse zu einem Film erstellt wurden, als Filminformationen behandeln. Bereiten Sie in bookinfo.html die Schaltfläche "Als Filminformationen senden" vor und schreiben Sie sie neu, sodass BookForm an die letzte gesendet wird.

bookinfo.html (erheblich geändert)

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>Tauschen Sie Werte von BookForm zu MoiveForm</h3>
	<form th:action="@{/movieinfo}" method="post" th:object="${bookForm}">
	<label>Titel</label><br>
	<input type="text" readonly th:field="*{title}"><br>
	<label>Preis</label><br>
	<input type="text" readonly th:field="*{price}"><br>
	<label>Überblick</label><br>
	<input type="text" readonly name="summary" th:value="*{summary}"><br>
	<button>Wird auch als Filminformation gesendet</button>
	</form>

SampleController.java (zusätzlicher Hinweis)

	//Bildschirm zur Ausgabe von Filminformationen (zusätzliche Informationen)
	@PostMapping("/movieinfo")
	public String toMovieinfo(@ModelAttribute("movieForm") MovieForm movieForm) {
		return "movieinfo";
	}

movieinfo.html

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>Tauschen Sie Werte von BookForm zu MoiveForm</h3>
	<div th:object="${movieForm}">
	<label>Titel</label><br>
	<span th:text="*{title}"></span><br>
	<label>Überblick</label><br>
	<span th:text="*{summary}"></span><br>
	</div>

Das Verarbeitungsergebnis ist wie folgt. スクリーンショット 2018-11-11 19.18.16.png スクリーンショット 2018-11-11 19.18.31.png

Der auf diese Weise als BookForm-Klasse gesendete Wert wird in MovieForm gespeichert und in movieinfo.html ausgegeben. Es ist eine leicht verdrehte Implementierung, so dass einige Leute möglicherweise ein seltsames Gefühl haben.

Der Punkt ist, dass BookForm und MovieForm Felder mit demselben Namen haben, wie z. B. "Titel" und "Zusammenfassung". Ich habe zwei Typen in bookinfo.html geschrieben, aber in diesem Verarbeitungsergebnis

<input type="text" readonly th:field="*{title}"> Ist <input type =" text "schreibgeschützt name =" title "value =" AIUEO ">

<input type="text" readonly name="summary" th:value="*{summary}"> Ist <input type =" text "schreibgeschützt name =" summary "value =" test ">

Hat die gleiche Bedeutung wie. Mit anderen Worten, der Wert des Attributs ** name entspricht dem Feldnamen von Form **, daher gibt es ein Tsuji 褄.

Geben Sie einen Wert für die Schaltfläche an und empfangen Sie ihn in der Formularklasse

** Oh, kann es implementiert werden, ohne das Feld th: zu verwenden? ** ** ** Wird es mir nicht in den Sinn kommen?

Betrachten wir nun den Erhalt des für die Schaltfläche angegebenen Werts. Fügen Sie MovieForm ein Kategoriefeld wie das folgende hinzu, um Schaltflächen für jede Kategorie in bookinfo.html hinzuzufügen. Der Text wird abhängig von der Taste, die Sie drücken, in movieinfo.html angezeigt.

MovieForm.java

public class MovieForm {

	private String title;
	private String summary;
	//Kategoriefeld hinzugefügt
	private String category;
	//	Getter,Setter weggelassen
}

bookinfo.html (Mehrere Schaltflächen mit Werten in der Kategorie hinzufügen)

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>Geben Sie einen Wert für die Schaltfläche an und empfangen Sie ihn in der Formularklasse</h3>
	<form th:action="@{/movieinfo}" method="post" th:object="${bookForm}">
	<label>Titel</label><br>
	<input type="text" readonly th:field="*{title}"><br>
	<label>Preis</label><br>
	<input type="text" readonly th:field="*{price}"><br>
	<label>Überblick</label><br>
	<input type="text" readonly name="summary" th:value="*{summary}"><br>
	<button name="category" value="Aktion">Aktion映画として送信</button>
	<button name="category" value="Fantasie">Fantasie映画として送信</button>
	<button name="category" value="SF">Als SF-Film senden</button>
	</form>

movieinfo.html

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>Geben Sie einen Wert für die Schaltfläche an und empfangen Sie ihn in der Formularklasse</h3>
	<div th:object="${movieForm}">
	<label>Titel</label><br>
	<span th:text="*{title}"></span><br>
	<label>Überblick</label><br>
	<span th:text="*{summary}"></span><br>
Die Kategorie ist<span th:text="*{category}"></span>ist.
	</div>

Das Ergebnis ist wie folgt

Wenn Sie nur "th: field" verwenden, ist es schwierig, den Wertwert des Elements zu ändern, der nicht eingegeben werden kann. Wenn Sie jedoch wissen, dass ** Namenswert und Wertwert ** wie folgt verknüpft sind Es ist auch möglich, die Verarbeitung abhängig vom Wert der Schaltfläche zu ändern.

Formularklasse löschen

Als letzten Schritt werden wir die Form-Klasse löschen. Die Annotation @ RequestParam spielt hier eine aktive Rolle.

Die Implementierung, die den eingegebenen Wert ausgibt, ist wie folgt.

input.html → Siehe [Feld löschen: th und Objekt in input.html löschen](Feld und Objekt in #inputhtml löschen)

SampleController.java

@Controller
public class SampleController {

	//Eingabebildschirm
	@GetMapping("/input")
	public String input() {
		return "input";
	}

	//Bildschirm zur Ausgabe von Buchinformationen
	@PostMapping("/bookinfo")
	public String toBookInfo(@RequestParam Map<String, String> bookmap, Model model) {
		model.addAttribute("bookmap", bookmap);
		return "bookinfo";
	}
}

bookinfo.html

	<!--Nur innerhalb der Registerkarte Körper-->
	<h3>Formularklasse löschen</h3>
	<label>Titel</label><br>
	<span th:text="${bookmap.title}"></span><br>
	<label>Preis</label><br>
	<span th:text="${bookmap.price}"></span><br>
	<label>Memo</label><br>
	<span th:text="${bookmap.summary}"></span><br>

Jetzt können Sie das gleiche Ergebnis wie bei der allgemeinen Implementierung (#Allgemeine Implementierung) erhalten, ohne eine Formularklasse zu verwenden. Wenn der in input.html mit @ RequestParam eingegebene Wert in Map empfangen wird, wird der Wert in bookinfo in Form von {title = AIUEO, price = 1000, summary = test} gespeichert. Sie können gut sehen, dass der ** Namenswert und der Wertwert **, die ich in diesem Artikel oft erwähnt habe, in Verbindung miteinander gesendet werden.

Der Vorteil dieser Implementierung besteht auch darin, dass Sie den einzugebenden Wert ändern können.

Auslöser und Ergänzung

Zunächst dachte ich "Ich möchte" th: field`` löschen ", weil ich einen variablen Eingabebildschirm erstellen musste.

Aufgrund verschiedener Schlussfolgerungen denke ich, dass Sie, wenn Sie "th: field" verwenden können, es aktiv verwenden sollten und nicht bis zu "@ RequestParam" verwenden sollten, um die Formularklasse zu löschen.

In der Implementierung, in der der Eingabewert von Map mit @ RequestParam empfangen wird, Behandlung von Werten, wenn eine Zurück-Schaltfläche vorhanden ist Fehlerbehandlung (Spring Framework-Anmerkungen können natürlich nicht verwendet werden) Und so weiter.

Auch in diesem Beispiel kann es ausreichen, einen Wert für die Schaltfläche anzugeben und ihn zu empfangen, aber ich denke, wenn Sie [Swap Form class](Swap #Form class) ausführen, wird die Lesbarkeit erheblich verringert. Ich werde.

Zusammenfassung

** th: Feld bedeutet Name und Wert (und ID) Attribute in HTML ** ** Der Wert des Wertattributs wird in Verbindung mit dem im Namensattribut angegebenen Wert gesendet und von der Controllerseite empfangen ** das ist alles!

Referenz

Spring MVC populate @RequestParam Map<String, String> Argumente für Spring MVC Controller

Wie Sie in den Kommentaren sehen können, enthält dieser Artikel weitere Details zum Verhalten von th: field. Formularbindungsfunktion nach th: Feld und th: Objekt (Eingabe-Tag / grundlegendes Eingabesystem)

Recommended Posts

Die Bedeutung von th: field in Thymeleaf und der Mechanismus der Übergabe von Werten von Spring Framework
Spielen Sie Framework, um das Übergeben von Werten zu studieren, und bilden Sie einen Helfer