Voorbeeldtoepassing met Spring Boot en Vaadin

1. Overzicht

Vaadin is een server-side Java-framework voor het maken van webgebruikersinterfaces.

In deze zelfstudie onderzoeken we hoe u een Op Vaadin gebaseerde gebruikersinterface op een op Spring Boot gebaseerde backend. Raadpleeg deze tutorial voor een inleiding tot Vaadin.

2. Installatie

Laten we beginnen met het toevoegen van Maven-afhankelijkheden aan een standaard Spring Boot-applicatie:

 com.vaadin vaadin-spring-boot-starter 

Vaadin is ook een erkende afhankelijkheid door de Spring Initializer.

In deze tutorial wordt een nieuwere versie van Vaadin gebruikt dan de standaardversie van de startermodule. Om de nieuwere versie te gebruiken, definieert u eenvoudig de Vaadin Bill of Materials (BOM) als volgt:

   com.vaadin vaadin-bom 10.0.11 pom importeren 

3. Backend-service

We gebruiken een Werknemer entiteit met Voornaam en achternaam eigenschappen om CRUD-bewerkingen erop uit te voeren:

@Entity openbare klasse Medewerker {@Id @GeneratedValue privé Lange id; private String voornaam; private String achternaam; }

Hier is de eenvoudige, overeenkomstige Spring Data-repository - om de CRUD-bewerkingen te beheren:

openbare interface EmployeeRepository breidt JpaRepository {List findByLastNameStartsWithIgnoreCase (String lastName) uit; }

We verklaren de vraagmethode findByLastNameStartsWithIgnoreCase op de WerknemerRepository koppel. Het retourneert de lijst met Werknemers die overeenkomen met de achternaam.

Laten we ook de DB vooraf vullen met een paar voorbeelden Werknemers:

@Bean openbare CommandLineRunner loadData (EmployeeRepository repository) {return (args) -> {repository.save (nieuwe medewerker ("Bill", "Gates")); repository.save (nieuwe medewerker ("Mark", "Zuckerberg")); repository.save (nieuwe medewerker ("Sundar", "Pichai")); repository.save (nieuwe medewerker ("Jeff", "Bezos")); }; }

4. Vaadin UI

4.1. Hoofdaanzicht Klasse

De Hoofdaanzicht class is het startpunt voor de UI-logica van Vaadin. Annotatie @Route vertelt Spring Boot om het automatisch op te halen en weer te geven in de root van de webapp:

@Route openbare klasse MainView breidt VerticalLayout uit {privé EmployeeRepository employeeRepository; privémedewerkerredacteur; Raster raster; TextField-filter; privéknop addNewBtn; }

We kunnen de URL aanpassen waar de weergave wordt weergegeven door een parameter te geven aan de @Route annotatie:

@Route (value = "myhome")

De klasse gebruikt de volgende UI-componenten die op de pagina worden weergegeven:

Medewerker Editor - toont de Werknemer formulier dat wordt gebruikt om werknemersinformatie te verstrekken om te maken en te bewerken.

Raster raster - omgorden om de lijst met Werknemers

TextField-filter - tekstveld om de achternaam in te voeren op basis waarvan de gordel zal worden gefilterd

Knop addNewBtn - Knop om een ​​nieuw toe te voegen Werknemer. Geeft het MedewerkerEditor editor.

Het maakt intern gebruik van de werknemerRepository om de CRUD-bewerkingen uit te voeren.

4.2. De componenten met elkaar verbinden

Hoofdaanzicht strekt zich uit Verticale indeling. Verticale indeling is een componentcontainer, die de subcomponenten toont in de volgorde van toevoeging (verticaal).

Vervolgens initialiseren en voegen we de componenten toe.

We voorzien de knop van een label met een + -pictogram.

this.grid = new Grid (Employee.class); this.filter = new TextField (); this.addNewBtn = nieuwe knop ("Nieuwe medewerker", VaadinIcon.PLUS.create ());

We gebruiken Horizontale indeling om het filtertekstveld en de knop horizontaal te rangschikken. Voeg vervolgens deze lay-out, gordel en editor toe aan de bovenliggende verticale lay-out:

HorizontalLayout-acties = nieuwe HorizontalLayout (filter, addNewBtn); toevoegen (acties, raster, editor);

Geef de gordelhoogte en kolomnamen op. We voegen ook helptekst toe in het tekstveld:

grid.setHeight ("200px"); grid.setColumns ("id", "voornaam", "achternaam"); grid.getColumnByKey ("id"). setWidth ("50px"). setFlexGrow (0); filter.setPlaceholder ("Filter op achternaam");

Bij het opstarten van de applicatie ziet de gebruikersinterface er als volgt uit:

4.3. Logica toevoegen aan componenten

We gaan zitten WaardeChangeMode.EAGER naar de filter tekstveld. Dit synchroniseert de waarde naar de server elke keer dat deze op de client wordt gewijzigd.

We hebben ook een listener ingesteld voor de waardewijzigingsgebeurtenis, die de gefilterde lijst met werknemers retourneert op basis van de tekst in het filter:

filter.setValueChangeMode (ValueChangeMode.EAGER); filter.addValueChangeListener (e -> listEmployees (e.getValue ()));

Bij het selecteren van een rij binnen de gordel, zouden we de Werknemer formulier, waardoor de gebruiker de voornaam en achternaam kan bewerken:

grid.asSingleSelect (). addValueChangeListener (e -> {editor.editEmployee (e.getValue ());});

Als we op de knop Nieuwe medewerker toevoegen klikken, laten we de blanco zien Werknemer het formulier:

addNewBtn.addClickListener (e -> editor.editEmployee (nieuwe werknemer ("", "")));

Ten slotte luisteren we naar de wijzigingen die door de editor zijn aangebracht en verversen we het raster met gegevens uit de backend:

editor.setChangeHandler (() -> {editor.setVisible (false); listEmployees (filter.getValue ());});

De listMedewerkers functie haalt de gefilterde lijst van Werknemers en werkt het raster bij:

void listEmployees (String filterText) {if (StringUtils.isEmpty (filterText)) {grid.setItems (employeeRepository.findAll ()); } anders {grid.setItems (employeeRepository.findByLastNameStartsWithIgnoreCase (filterText)); }}

4.4. Het formulier opbouwen

We gebruiken een eenvoudig formulier waarmee de gebruiker een medewerker kan toevoegen / bewerken:

@SpringComponent @UIScope publieke klasse EmployeeEditor breidt VerticalLayout uit implementeert KeyNotifier {private EmployeeRepository repository; particulier Medewerker werknemer; TextField firstName = nieuw TextField ("Voornaam"); TextField lastName = nieuw TextField ("Achternaam"); Button save = nieuwe Button ("Save", VaadinIcon.CHECK.create ()); Knop annuleren = nieuwe knop ("Annuleren"); Knop verwijderen = nieuwe knop ("Verwijderen", VaadinIcon.TRASH.create ()); HorizontalLayout-acties = nieuwe HorizontalLayout (opslaan, annuleren, verwijderen); Binder binder = nieuwe Binder (Employee.class); privé ChangeHandler changeHandler; }

De @SpringComponent is slechts een alias voor Springs @Component annotatie om conflicten met Vaadins te vermijden Component klasse.

De @UIScope bindt de boon aan de huidige gebruikersinterface van Vaadin.

Momenteel bewerkt Werknemer wordt opgeslagen in de werknemer lid variabele. We vangen de Werknemer eigenschappen door Voornaam en achternaam tekstvelden.

Het formulier heeft drie knoppen - sparen, annuleren en verwijderen.

Zodra alle componenten met elkaar zijn verbonden, ziet het formulier er als volgt uit voor een rijenelectie:

We gebruiken een Binder die de formuliervelden bindt met de Werknemer eigenschappen met behulp van de naamgevingsconventie:

binder.bindInstanceFields (dit);

We noemen de juiste EmployeeRepositor-methode op basis van de gebruikershandelingen:

void delete () {repository.delete (medewerker); changeHandler.onChange (); } void save () {repository.save (medewerker); changeHandler.onChange (); }

5. Conclusie

In dit artikel hebben we een volledige CRUD UI-applicatie geschreven met Spring Boot en Spring Data JPA voor persistentie.

Zoals gewoonlijk is de code beschikbaar op GitHub.