Beispielanwendung mit Spring Boot und Vaadin

1. Übersicht

Vaadin ist ein serverseitiges Java-Framework zum Erstellen von Webbenutzeroberflächen .

In diesem Tutorial erfahren Sie, wie Sie eine Vaadin-basierte Benutzeroberfläche in einem Spring Boot-basierten Backend verwenden . Eine Einführung in Vaadin finden Sie in diesem Tutorial.

2. Setup

Beginnen wir mit dem Hinzufügen von Maven-Abhängigkeiten zu einer Standard-Spring Boot-Anwendung:

 com.vaadin vaadin-spring-boot-starter 

Vaadin ist auch eine vom Spring Initializer erkannte Abhängigkeit.

In diesem Tutorial wird eine neuere Version von Vaadin verwendet als die vom Startermodul bereitgestellte Standardversion. Um die neuere Version zu verwenden, definieren Sie einfach die Vaadin-Stückliste wie folgt:

   com.vaadin vaadin-bom 10.0.11 pom import   

3. Backend-Service

Wir werden eine Employee- Entität mit den Eigenschaften firstName und lastName verwenden, um CRUD-Operationen daran auszuführen:

@Entity public class Employee { @Id @GeneratedValue private Long id; private String firstName; private String lastName; }

Hier ist das einfache, entsprechende Spring Data-Repository - zum Verwalten der CRUD-Operationen:

public interface EmployeeRepository extends JpaRepository { List findByLastNameStartsWithIgnoreCase(String lastName); }

Wir deklarieren die Abfragemethode findByLastNameStartsWithIgnoreCase auf der EmployeeRepository- Schnittstelle. Es wird die Liste der Mitarbeiter zurückgegeben, die mit dem Nachnamen übereinstimmen .

Lassen Sie uns auch die Datenbank mit einigen Beispielmitarbeitern vorab füllen :

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

4. Vaadin UI

4.1. MainView- Klasse

Die MainView- Klasse ist der Einstiegspunkt für die UI-Logik von Vaadin. Annotation @Route weist Spring Boot an, es automatisch aufzunehmen und im Stammverzeichnis der Web-App anzuzeigen :

@Route public class MainView extends VerticalLayout { private EmployeeRepository employeeRepository; private EmployeeEditor editor; Grid grid; TextField filter; private Button addNewBtn; }

Wir können die URL anpassen, unter der die Ansicht angezeigt wird, indem wir der Annotation @Route einen Parameter zuweisen :

@Route(value="myhome")

Die Klasse verwendet die folgenden UI-Komponenten, die auf der Seite angezeigt werden sollen:

EmployeeEditor-Editor - Zeigt das Mitarbeiterformular an, mit dem Mitarbeiterinformationen zum Erstellen und Bearbeiten bereitgestellt werden.

Gitter Gitter - Gürteln, um die Liste der Mitarbeiter anzuzeigen

TextField-Filter - Textfeld zur Eingabe des Nachnamens, anhand dessen der Gürtel gefiltert wird

Schaltfläche addNewBtn - Schaltfläche zum Hinzufügen eines neuen Mitarbeiters . Zeigt den EmployeeEditor- Editor an.

Es verwendet intern das employeeRepository , um die CRUD-Operationen auszuführen.

4.2. Verdrahtung der Komponenten

MainView erweitert VerticalLayout . VerticalLayout ist ein Komponentencontainer, der die Unterkomponenten in der Reihenfolge ihrer Hinzufügung (vertikal) anzeigt .

Als nächstes initialisieren und fügen wir die Komponenten hinzu.

Wir versehen die Schaltfläche mit einem + -Symbol.

this.grid = new Grid(Employee.class); this.filter = new TextField(); this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create());

Wir verwenden HorizontalLayout , um das Filtertextfeld und die Schaltfläche horizontal anzuordnen. Fügen Sie dann dieses Layout, diesen Gürtel und diesen Editor zum übergeordneten vertikalen Layout hinzu:

HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn); add(actions, grid, editor);

Geben Sie die Gürtelhöhe und die Spaltennamen an. Wir fügen auch Hilfetext in das Textfeld ein:

grid.setHeight("200px"); grid.setColumns("id", "firstName", "lastName"); grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0); filter.setPlaceholder("Filter by last name");

Beim Start der Anwendung würde die Benutzeroberfläche folgendermaßen aussehen:

4.3. Hinzufügen von Logik zu Komponenten

Wir setzen ValueChangeMode.EAGER auf das Filtertextfeld . Dadurch wird der Wert bei jeder Änderung auf dem Client mit dem Server synchronisiert.

Wir haben auch einen Listener für das Wertänderungsereignis festgelegt, der die gefilterte Liste der Mitarbeiter basierend auf dem im Filter angegebenen Text zurückgibt :

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

Bei Auswahl einer Zeile innerhalb des Gürtels wird das Mitarbeiterformular angezeigt, in dem der Benutzer den Vor- und Nachnamen bearbeiten kann:

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

Wenn Sie auf die Schaltfläche Neuen Mitarbeiter hinzufügen klicken, wird das leere Mitarbeiterformular angezeigt:

addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", "")));

Finally, we listen to the changes made by the editor and refresh the grid with data from the backend:

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

The listEmployees function gets the filtered list of Employees and updates the grid:

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

4.4. Building the Form

We'll use a simple form for the user to add/edit an employee:

@SpringComponent @UIScope public class EmployeeEditor extends VerticalLayout implements KeyNotifier { private EmployeeRepository repository; private Employee employee; TextField firstName = new TextField("First name"); TextField lastName = new TextField("Last name"); Button save = new Button("Save", VaadinIcon.CHECK.create()); Button cancel = new Button("Cancel"); Button delete = new Button("Delete", VaadinIcon.TRASH.create()); HorizontalLayout actions = new HorizontalLayout(save, cancel, delete); Binder binder = new Binder(Employee.class); private ChangeHandler changeHandler; }

The @SpringComponent is just an alias to Springs @Component annotation to avoid conflicts with Vaadins Component class.

The @UIScope binds the bean to the current Vaadin UI.

Currently, edited Employee is stored in the employee member variable. We capture the Employee properties through firstName and lastName text fields.

The form has three button – save, cancel and delete.

Once all the components are wired together, the form would look as below for a row selection:

We use a Binder which binds the form fields with the Employee properties using the naming convention:

binder.bindInstanceFields(this);

We call the appropriate EmployeeRepositor method based on the user operations:

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

5. Conclusion

In diesem Artikel haben wir eine CRUD-UI-Anwendung mit vollem Funktionsumfang geschrieben, die Spring Boot und Spring Data JPA verwendet, um die Persistenz zu gewährleisten.

Wie üblich ist der Code auf GitHub verfügbar.