OriginaldokumentationZweiter TeilDritter TeilInhaltsverzeichnis:
1. Thymeleaf Integration mit dem Frühling
2. SpringStandard-Dialekt
3. Ansichten und Ansichtsauflöser
3.1 Ansichten und Ansichtsauflöser in Spring MVC
3.2 Ansichten und Ansichtsauflöser in Thymeleaf
4. Spring Thyme Seed Starter Manager
4.1 Konzept
4.2 Geschäftsschicht
4.3 Spring MVC-Konfiguration
4.4 Controller
4.5 Konvertierungsdienst konfigurieren
5 Seed Starter-Daten anzeigen
6 Formulare erstellen
6.1 Befehlsobjekt verarbeiten
6.2 Eingänge
6.3 Kontrollkästchenfelder
6.4 Optionsfeldfelder
6.5 Dropdown- / Listenselektoren
6.6 Dynamische Felder
7 Überprüfungs- und Fehlermeldungen
7.1 Feldfehler
7.2 Alle Fehler
7.3 Globale Fehler
7.4 Fehler außerhalb von Formularen anzeigen
7.5 Rich-Error-Objekte
8 Dies ist immer noch ein Prototyp!
9 Der Konvertierungsdienst
9.1 Konfiguration
9.2 Syntax in doppelten Klammern
9.3 Verwendung in Formularen
9.4 Konvertierungsobjekt #conversions
10 Rendern von Fragmenten der Vorlage Vorlagenfragmente (AJAX usw.)
10.1 Fragmente in einer View Bean definieren
10.2 Fragmente im Rückgabewert der Steuerung definieren
11 Erweiterte Integrationsfunktionen
11.1 Integration mit RequestDataValueProcessor
11.1 URIs für Controller erstellen
12 Spring WebFlow-Integration
12.2 AJAX-Snippets in Spring WebFlow
In diesem Handbuch wird erläutert, wie
Thymeleaf in das Spring Framework integriert werden kann, insbesondere (aber nicht nur) Spring MVC.
Beachten Sie, dass Thymeleaf über Integrationen für die Versionen 3.x und 4.x des Spring Framework und höher verfügt, die von zwei separaten Bibliotheken namens thymeleaf-spring3 und thymeleaf-spring4 bereitgestellt werden. Diese Bibliotheken sind in separaten JAR-Dateien (thymeleaf-spring3- {version} .jar und thymeleaf-spring4- {version} .jar) verpackt und müssen Ihrem Klassenpfad hinzugefügt werden, um die Thymeleaf Spring-Integrationen in Ihrer Anwendung verwenden zu können.
Die Codebeispiele und Beispielanwendungen in diesem Handbuch verwenden Spring 4.x und die entsprechenden Thymeleaf-Integrationen. Der Inhalt dieses Textes gilt jedoch auch für Spring 3.x. Wenn Ihre Anwendung Spring 3.x verwendet, müssen Sie lediglich das Paket org.thymeleaf.spring4 in den Codebeispielen durch org.thymeleaf.spring3 ersetzen.
1. Thymeleaf Integration mit dem Frühling
Thymeleaf bietet eine Reihe von Spring-Integrationen, mit denen es als JSP-Ersatz mit vollem Funktionsumfang in Spring-MVC-Anwendungen verwendet werden kann.
Mit diesen Integrationen können Sie:
- Erstellen Sie eine Zuordnung zu den Methoden in Ihren Spring MVC Controller- Objekten von Mustern, die von Thymeleaf verwaltet werden, genau wie Sie es mit JSP tun.
- Verwenden Sie in Ihren Vorlagen Spring Expression Language (Spring EL) anstelle von OGNL.
- Erstellen Sie Formulare in Ihren Vorlagen, die vollständig in Ihre Formularunterstützungskomponenten und Beans integriert sind, einschließlich der Verwendung von Eigenschaftseditoren, Konvertierungsdiensten und der Behandlung von Validierungsfehlern.
- Anzeigen von Internationalisierungsnachrichten aus von Spring verwalteten Nachrichtendateien (über reguläre MessageSource-Objekte).
- Finden Sie Ihre Muster mithilfe nativer Spring-Ressourcenauflösungsmechanismen.
Bitte beachten Sie, dass Sie zum vollständigen Verständnis dieses Lernprogramms zunächst das
Lernprogramm „
Verwenden von Thymeleaf “
durchgehen müssen , in dem der Standarddialekt ausführlich erläutert wird.
2. SpringStandard-Dialekt
Um eine einfachere und bessere Integration zu erreichen, bietet Thymeleaf einen Dialekt, der speziell alle erforderlichen Funktionen für die korrekte Arbeit mit Spring implementiert.
Dieser spezielle Dialekt basiert auf dem Standard-Thymeleaf-Dialekt und ist in der Klasse org.thymeleaf.spring4.dialect.SpringStandardDialect implementiert, die tatsächlich von org.thymeleaf.standard.StandardDialect abgeleitet ist.
Zusätzlich zu allen Funktionen, die bereits im Standarddialekt vorhanden und daher vererbt sind, bietet SpringStandard Dialect die folgenden spezifischen Funktionen:
- Verwenden der Spring-Ausdruckssprache (Spring EL oder SpEL) als variable Ausdruckssprache, nicht OGNL. Daher werden alle $ {...} und * {...} Ausdrücke von der Spring-Ausdruckssprachen-Engine ausgewertet. Beachten Sie auch, dass die Unterstützung des Spring EL-Compilers (Spring 4.2.4+) verfügbar ist.
- Zugriff auf alle Komponenten im Kontext Ihrer Anwendung mithilfe der SpringEL-Syntax: $ {@ myBean.doSomething ()}
- Neue Attribute für die Verarbeitung des Formulars: th: Feld , th: Fehler und th: Fehlerklasse , mit Ausnahme der neuen Implementierung des Objekts th: object , mit der Sie den Befehl form auswählen können.
- Die Objekt- und Ausdrucksmethode lautet # theme.code (...) und entspricht dem benutzerdefinierten JSP-Tag spring: theme .
- Die Objekt- und Ausdrucksmethode # mvc.uri (...) , die der benutzerdefinierten JSP- Federfunktion entspricht : mvcUrl (...) (nur in Spring 4.1+).
Beachten Sie, dass Sie diesen Dialekt in den meisten Fällen nicht direkt in einem regulären TemplateEngine-Objekt als Teil seiner Konfiguration verwenden sollten. Wenn Sie keine besonderen Integrationsanforderungen für Spring haben, sollten Sie stattdessen eine Instanz einer neuen Vorlagenklasse erstellen, die automatisch alle erforderlichen Konfigurationsschritte ausführt:
org.thymeleaf.spring4.SpringTemplateEngine .
Bean-Konfigurationsbeispiel:
@Bean public SpringResourceTemplateResolver templateResolver(){
Oder verwenden Sie die XML-basierte Spring-Konfiguration:
<bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver"> <property name="prefix" value="/WEB-INF/templates/" /> <property name="suffix" value=".html" /> <property name="templateMode" value="HTML" /> <property name="cacheable" value="true" /> </bean> <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"> <property name="templateResolver" ref="templateResolver" /> <property name="enableSpringELCompiler" value="true" /> </bean>
3. Ansichten und Ansichtsauflöser
3.1 Ansichten und Ansichtsauflöser in Spring MVC
Spring MVC verfügt über zwei Schnittstellen, die dem Kern seines Vorlagensystems entsprechen:
- org.springframework.web.servlet.View
- org.springframework.web.servlet.ViewResolver
Zeigt Modellseiten in unseren Anwendungen an und ermöglicht es Ihnen, deren Verhalten zu ändern und vorab festzulegen, indem Sie sie als Bean-Komponenten definieren. Ansichten sind in der Regel für das Rendern der realen HTML-Oberfläche verantwortlich, um eine Art Template-Engine auszuführen, beispielsweise Thymeleaf.
ViewResolver sind Objekte, die für das
Abrufen von View- Objekten für eine bestimmte Operation und ein bestimmtes Gebietsschema verantwortlich sind. In der Regel fordern Controller ViewResolvers an, die Ansicht mit einem bestimmten Namen (der von der Controller-Methode zurückgegebenen Zeichenfolge) weiterzuleiten. Anschließend werden alle Mittel zum Auflösen der Ansicht in der Anwendung in einer geordneten Kette ausgeführt, bis einer von ihnen diese Ansicht auflösen kann. In diesem Fall wird das View-Objekt zurückgegeben und das Steuerelement an sie übertragen zum Rendern von HTML.
Bitte beachten Sie, dass nicht alle Seiten in unseren Anwendungen als Ansichten definiert werden sollten, sondern nur diejenigen, deren Verhalten nicht standardisiert oder auf besondere Weise angepasst werden soll (z. B. durch Anschließen einiger spezieller Komponenten). Wenn ein ViewResolver für eine Ansicht angefordert wird, die keine entsprechende Bean enthält (was häufig der Fall ist), wird eine neue Ansicht ad hoc erstellt und zurückgegeben.Eine typische
JSP + JSTL ViewResolver-Konfiguration in einer Spring MVC-Anwendung aus der Vergangenheit sah folgendermaßen aus:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsps/" /> <property name="suffix" value=".jsp" /> <property name="order" value="2" /> <property name="viewNames" value="*jsp" /> </bean>
Ein kurzer Blick auf die Eigenschaften reicht aus, um herauszufinden, wie es konfiguriert wurde:
- viewClass legt die Klasse der View-Instanzen fest. Dies ist für den JSP-Erkenner erforderlich, aber überhaupt nicht, wenn wir mit Thymeleaf arbeiten.
- Das Präfix und das Suffix funktionieren ähnlich wie Attribute mit demselben Namen in Thymeleaf TemplateResolver-Objekten.
- order legt die Reihenfolge fest, in der der ViewResolver in der Kette angefordert wird.
- Mit viewNames können Sie (mit Platzhaltern) die Namen der Ansichten definieren, die dieser ViewResolver auflösen wird.
3.2 Ansichten und Ansichtsauflöser in Thymeleaf
Thymeleaf bietet Implementierungen für die beiden oben genannten Schnittstellen an:
- org.thymeleaf.spring4.view.ThymeleafView
- org.thymeleaf.spring4.view.ThymeleafViewResolver
Diese beiden Klassen sind für die Verarbeitung von Thymeleaf-Vorlagen verantwortlich, die sich aus der Ausführung der Controller ergeben.
Die Konfiguration der Resolver Thymeleaf View ist der JSP sehr ähnlich:
@Bean public ThymeleafViewResolver viewResolver(){ ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setTemplateEngine(templateEngine());
... oder in XML:
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver"> <property name="templateEngine" ref="templateEngine" /> <property name="order" value="1" /> <property name="viewNames" value="*.html,*.xhtml" /> </bean>
Der Parameter
templateEngine ist natürlich das SpringTemplateEngine-Objekt, das wir im vorherigen Kapitel definiert haben. Die beiden anderen (
order und
viewNames ) sind optional und haben dieselbe Bedeutung wie im JSP ViewResolver, den wir zuvor gesehen haben.
Bitte beachten Sie, dass wir keine Präfix- oder Suffix-Parameter benötigen, da diese bereits im Template Resolver angegeben sind (der wiederum an die Template Engine übergeben wird).
Was aber, wenn wir eine
View-Bean definieren und ihr
einige statische Variablen hinzufügen möchten? Einfach, definieren Sie einfach einen Prototyp dafür:
@Bean @Scope("prototype") public ThymeleafView mainView() { ThymeleafView view = new ThymeleafView("main");
Anschließend können Sie diese Komponente anfordern, indem Sie sie nach Namen auswählen (in diesem Fall mainView).
4. Spring Thyme Seed Starter Manager
Der Quellcode für die in diesem und den folgenden Kapiteln dieses Handbuchs gezeigten Beispiele befindet sich im
GitHub Spring Seyme Seed Starter Manager- Repository.
4.1 Konzept
In Bezug auf Thymeleaf sind wir große Fans von Thymian, und jedes Frühjahr bereiten wir unsere Starter-Kits mit gutem Boden und unseren Lieblingssamen vor, pflanzen sie unter der spanischen Sonne und warten geduldig auf das Wachstum unserer neuen Pflanzen.
In diesem Jahr hatten wir es jedoch satt, Etiketten auf die
Startsamenbehälter zu
kleben , um herauszufinden, welche Samen sich in den einzelnen Zellen des Behälters befanden.
Deshalb haben wir beschlossen, die Anwendung mit Spring MVC und
Thymeleaf vorzubereiten , um unsere Starter zu katalogisieren:
Spring Thyme SeedStarter Manager .

Ähnlich wie die Good Thymes Virtual Grocery-Anwendung, die wir im Tutorial Using Thymeleaf entwickelt haben, können wir mit STSM die wichtigsten Aspekte der Integration von Thymeleaf als Template-Engine für Spring MVC demonstrieren.
4.2 Geschäftsschicht
Wir benötigen eine sehr einfache Geschäftsschicht für unsere Anwendung. Schauen wir uns zunächst unsere Modellobjekte an:

Einige sehr einfache Serviceklassen bieten die erforderlichen Geschäftsmethoden. Wie:
@Service public class SeedStarterService { @Autowired private SeedStarterRepository seedstarterRepository; public List<SeedStarter> findAll() { return this.seedstarterRepository.findAll(); } public void add(final SeedStarter seedStarter) { this.seedstarterRepository.add(seedStarter); } }
Und:
@Service public class VarietyService { @Autowired private VarietyRepository varietyRepository; public List<Variety> findAll() { return this.varietyRepository.findAll(); } public Variety findById(final Integer id) { return this.varietyRepository.findById(id); } }
4.3 Spring MVC-Konfiguration
Als Nächstes müssen wir
die Spring MVC-Konfiguration für die Anwendung
konfigurieren , die nicht nur Standard-Spring MVC-Artefakte wie Ressourcenverarbeitung oder Scannen von Anmerkungen enthält, sondern auch die Instanziierung der
Template Engine und des
View Resolver .
@Configuration @EnableWebMvc @ComponentScan public class SpringWebConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware { private ApplicationContext applicationContext; public SpringWebConfig() { super(); } public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void addResourceHandlers(final ResourceHandlerRegistry registry) { super.addResourceHandlers(registry); registry.addResourceHandler("/images/**").addResourceLocations("/images/"); registry.addResourceHandler("/css/**").addResourceLocations("/css/"); registry.addResourceHandler("/js/**").addResourceLocations("/js/"); } @Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("Messages"); return messageSource; } @Override public void addFormatters(final FormatterRegistry registry) { super.addFormatters(registry); registry.addFormatter(varietyFormatter()); registry.addFormatter(dateFormatter()); } @Bean public VarietyFormatter varietyFormatter() { return new VarietyFormatter(); } @Bean public DateFormatter dateFormatter() { return new DateFormatter(); } @Bean public SpringResourceTemplateResolver templateResolver(){
4.4 Controller
Natürlich brauchen wir auch einen Controller für unsere Anwendung. Da STSM nur eine Webseite mit einer Liste von Anfangswerten und einem Formular zum Hinzufügen neuer Werte enthält, schreiben wir nur eine Controller-Klasse für alle Serverinteraktionen:
@Controller public class SeedStarterMngController { @Autowired private VarietyService varietyService; @Autowired private SeedStarterService seedStarterService; ... }
Nun wollen wir sehen, was wir dieser Controller-Klasse hinzufügen können.
ModellattributeZuerst fügen wir einige Modellattribute hinzu, die wir auf der Seite benötigen:
@ModelAttribute("allTypes") public List<Type> populateTypes() { return Arrays.asList(Type.ALL); } @ModelAttribute("allFeatures") public List<Feature> populateFeatures() { return Arrays.asList(Feature.ALL); } @ModelAttribute("allVarieties") public List<Variety> populateVarieties() { return this.varietyService.findAll(); } @ModelAttribute("allSeedStarters") public List<SeedStarter> populateSeedStarters() { return this.seedStarterService.findAll(); }
Zugeordnete MethodenUnd jetzt der wichtigste Teil des Controllers, zugeordnete Methoden: eine zum Anzeigen der Formularseite und die andere zum Hinzufügen neuer
SeedStarter- Objekte.
@RequestMapping({"/","/seedstartermng"}) public String showSeedstarters(final SeedStarter seedStarter) { seedStarter.setDatePlanted(Calendar.getInstance().getTime()); return "seedstartermng"; } @RequestMapping(value="/seedstartermng", params={"save"}) public String saveSeedstarter( final SeedStarter seedStarter, final BindingResult bindingResult, final ModelMap model) { if (bindingResult.hasErrors()) { return "seedstartermng"; } this.seedStarterService.add(seedStarter); model.clear(); return "redirect:/seedstartermng"; }
4.5 Konvertierungsdienst konfigurieren
Um eine einfache Formatierung für
Datumsobjekte sowie für
Variety- Objekte in unserer Ansichtsebene bereitzustellen, haben wir unsere Anwendung so konfiguriert, dass das Spring
ConversionService- Objekt mithilfe
einiger der benötigten Formatierungsobjekte erstellt und initialisiert wurde (erweiterbarer
WebMvcConfigurerAdapter ).
Schauen Sie noch einmal:
@Override public void addFormatters(final FormatterRegistry registry) { super.addFormatters(registry); registry.addFormatter(varietyFormatter()); registry.addFormatter(dateFormatter()); } @Bean public VarietyFormatter varietyFormatter() { return new VarietyFormatter(); } @Bean public DateFormatter dateFormatter() { return new DateFormatter(); }
Spring-
Formatierer sind Implementierungen der Schnittstelle
org.springframework.format.Formatter . Weitere Informationen zur Funktionsweise der Spring-Konvertierungsinfrastruktur finden Sie in den Dokumenten auf
spring.io .
Schauen wir uns einen
DateFormatter an , der Datumsangaben gemäß der
Formatzeichenfolge formatiert, die im
date.format- Schlüssel unserer
Messages.properties enthalten ist :
public class DateFormatter implements Formatter<Date> { @Autowired private MessageSource messageSource; public DateFormatter() { super(); } public Date parse(final String text, final Locale locale) throws ParseException { final SimpleDateFormat dateFormat = createDateFormat(locale); return dateFormat.parse(text); } public String print(final Date object, final Locale locale) { final SimpleDateFormat dateFormat = createDateFormat(locale); return dateFormat.format(object); } private SimpleDateFormat createDateFormat(final Locale locale) { final String format = this.messageSource.getMessage("date.format", null, locale); final SimpleDateFormat dateFormat = new SimpleDateFormat(format); dateFormat.setLenient(false); return dateFormat; } }
VarietyFormatter konvertiert automatisch zwischen unseren
Variety- Objekten und der Art und Weise, wie wir sie in unseren Formularen verwenden möchten (hauptsächlich anhand der Werte ihrer
ID- Felder):
public class VarietyFormatter implements Formatter<Variety> { @Autowired private VarietyService varietyService; public VarietyFormatter() { super(); } public Variety parse(final String text, final Locale locale) throws ParseException { final Integer varietyId = Integer.valueOf(text); return this.varietyService.findById(varietyId); } public String print(final Variety object, final Locale locale) { return (object != null ? object.getId().toString() : ""); } }
Wir werden mehr darüber erfahren, wie sich diese Formatierungswerkzeuge in Zukunft auf die Art und Weise auswirken, wie wir unsere Daten anzeigen.