Applicazione di esempio con Spring Boot e Vaadin

1. Panoramica

Vaadin è un framework Java lato server per la creazione di interfacce utente web .

In questo tutorial, esploreremo come utilizzare un'interfaccia utente basata su Vaadin su un back-end basato su Spring Boot . Per un'introduzione a Vaadin fare riferimento a questo tutorial.

2. Configurazione

Cominciamo aggiungendo le dipendenze Maven a un'applicazione Spring Boot standard:

 com.vaadin vaadin-spring-boot-starter 

Vaadin è anche una dipendenza riconosciuta dallo Spring Initializer.

Questo tutorial utilizza una versione più recente di Vaadin rispetto a quella predefinita fornita dal modulo di avvio. Per utilizzare la versione più recente, è sufficiente definire la distinta materiali (BOM) Vaadin in questo modo:

   com.vaadin vaadin-bom 10.0.11 pom import   

3. Servizio di backend

Useremo un'entità Employee con proprietà firstName e lastName per eseguire operazioni CRUD su di essa:

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

Ecco il semplice repository Spring Data corrispondente - per gestire le operazioni CRUD:

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

Dichiariamo il metodo di query findByLastNameStartsWithIgnoreCase sull'interfaccia EmployeeRepository . Restituirà l'elenco dei dipendenti che corrispondono al lastName .

Prepopoliamo anche il database con alcuni dipendenti di esempio :

@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. Classe MainView

La classe MainView è il punto di ingresso per la logica dell'interfaccia utente di Vaadin. Annotation @Route dice a Spring Boot di raccoglierlo automaticamente e mostrarlo nella radice dell'app Web:

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

Possiamo personalizzare l'URL in cui viene mostrata la vista fornendo un parametro all'annotazione @Route :

@Route(value="myhome")

La classe utilizza i seguenti componenti dell'interfaccia utente da visualizzare nella pagina:

Editor EmployeeEditor : mostra il modulo Dipendente utilizzato per fornire le informazioni sui dipendenti da creare e modificare.

Grid grid - gird per visualizzare l'elenco dei dipendenti

TextField filter - campo di testo per inserire il cognome in base al quale verrà filtrato il gird

Pulsante addNewBtn - Pulsante per aggiungere un nuovo dipendente . Visualizza l' editor EmployeeEditor .

Utilizza internamente il EmployeeRepository per eseguire le operazioni CRUD.

4.2. Cablaggio dei componenti insieme

MainView estende VerticalLayout . VerticalLayout è un contenitore di componenti, che mostra i sottocomponenti nell'ordine in cui sono stati aggiunti (verticalmente).

Successivamente, inizializziamo e aggiungiamo i componenti.

Forniamo un'etichetta al pulsante con un'icona +.

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

Usiamo HorizontalLayout per disporre orizzontalmente il campo di testo del filtro e il pulsante. Quindi aggiungi questo layout, gird e editor nel layout verticale principale:

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

Fornire l'altezza della cintura e i nomi delle colonne. Aggiungiamo anche testo di aiuto nel campo di testo:

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

All'avvio dell'applicazione, l'interfaccia utente avrà questo aspetto:

4.3. Aggiunta di logica ai componenti

Imposteremo ValueChangeMode.EAGER nel campo di testo del filtro . Questo sincronizza il valore con il server ogni volta che viene modificato sul client.

Abbiamo anche impostato un listener per l'evento di modifica del valore, che restituisce l'elenco filtrato dei dipendenti in base al testo fornito nel filtro:

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

Selezionando una riga all'interno della cintura, mostreremo il modulo Dipendente , consentendo all'utente di modificare il nome e il cognome:

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

Facendo clic sul pulsante Aggiungi nuovo dipendente, mostreremo il modulo Dipendente vuoto :

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

Infine, ascoltiamo le modifiche apportate dall'editor e aggiorniamo la griglia con i dati dal backend:

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

La funzione listEmployees ottiene l'elenco filtrato di Employee e aggiorna la griglia:

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

4.4. Costruire la forma

Useremo un semplice modulo per consentire all'utente di aggiungere / modificare un dipendente:

@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; }

Il @SpringComponent è solo un alias per Springs @Component annotazioni per evitare conflitti con Vaadins componente di classe.

Il @UIScope si lega il fagiolo alla corrente Vaadin interfaccia utente.

Attualmente, il dipendente modificato è archiviato nella variabile membro del dipendente . Catturiamo le proprietà Employee tramite i campi di testo firstName e lastName .

Il modulo ha tre pulsanti: salva , annulla ed elimina .

Una volta che tutti i componenti sono collegati insieme, il modulo apparirà come di seguito per una selezione di righe:

Usiamo un Binder che lega i campi del modulo con le proprietà Employee usando la convenzione di denominazione :

binder.bindInstanceFields(this);

Chiamiamo il metodo EmployeeRepositor appropriato in base alle operazioni dell'utente:

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

5. conclusione

In questo articolo, abbiamo scritto un'applicazione UI CRUD completa che utilizza Spring Boot e Spring Data JPA per la persistenza.

Come al solito, il codice è disponibile su GitHub.