Cosa è Vaadin
- Panoramica
Vaadin Flow è un framework web full-stack per Java. Vaadin Flow è progettato per consentire agli sviluppatori Java di creare applicazioni web in Java, senza bisogno di JavaScript o HTML. Vaadin Flow può essere utilizzato per qualsiasi tipo di applicazione web, ma è particolarmente adatto per applicazioni aziendali ricche di dati.
Vaadin Flow si basa sull’ampio set di componenti Vaadin UI, con un’API Java intuitiva per la creazione di interfacce utente. In questo tutorial, tratteremo i concetti e le funzionalità principali di Vaadin Flow.
- Creazione di un progetto Vaadin Flow
Possiamo creare un progetto Vaadin Flow aggiungendo la dipendenza Vaadin in Spring Initalizr oppure scaricando uno starter personalizzato su Vaadin Start .
In alternativa, possiamo aggiungere Vaadin Flow a un progetto Spring Boot esistente, aggiungendo la seguente distinta base (BOM) in pom.xml . Inizializziamo la proprietà vaadin.version con l’ ultima versione di vaadin-bom .
<properties>
<vaadin.version>24.3.6</vaadin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Per completare la configurazione, aggiungiamo la seguente dipendenza:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
- Creazione di interfacce utente a partire da componenti
Vaadin Flow è un framework basato su componenti. Ogni componente è rappresentato da un oggetto Java:
var textField = new TextField("Name");
var button = new Button("Click me");
- Strutturare l’interfaccia utente con i layout
Possiamo creare viste dai componenti usando i Layout. I Layout controllano il posizionamento, l’allineamento e la spaziatura dei componenti. I layout di base sono HorizontalLayout e VerticalLayout . Possiamo creare layout più complessi combinando i due.
var verticalLayout = new VerticalLayout(
new Button("Top"),
new Button("Middle"),
new Button("Bottom")
);
var horizontalLayout = new HorizontalLayout(
new Button("Left"),
new Button("Center"),
new Button("Right")
);
Oltre a HorizontalLayout e VerticalLayout , Vaadin Flow include layout per casi d’uso più specifici:
- FormLayout : per i moduli in cui le etichette di input devono essere posizionate accanto al campo.
- SplitLayout : per separare due aree di contenuto con uno splitter ridimensionabile.
- Div : per controllare il posizionamento dei contenuti tramite CSS (avanzato).
Ecco come abbiamo messo insieme il tutto per creare un layout più complesso con uno SplitLayout ridimensionabile come layout padre, un componente Grid come primo componente e un VerticalLayout che annida un HorizontalLayout come secondo componente.
public class ExampleLayout extends SplitLayout {
public ExampleLayout() {
var grid = new Grid<>(Contact.class);
grid.setColumns("name", "email", "phone");
grid.setItems(List.of(
new Contact("John Doe", "john@doe.com", "123 456 789"),
new Contact("Jane Doe", "jane@doe.com", "987 654 321")
));
var form = new VerticalLayout();
var nameField = new TextField("Name");
var emailField = new TextField("Email");
var phoneField = new TextField("Phone");
var saveButton = new Button("Save");
var cancelButton = new Button("Cancel");
form.add(
nameField,
emailField,
phoneField,
new HorizontalLayout(saveButton, cancelButton)
);
setSizeFull();
setSplitterPosition(70);
addToPrimary(grid);
addToSecondary(form);
}
}
- Trasformare un componente in una vista con @Route
Possiamo trasformare qualsiasi componente, più spesso un layout, in una vista annotandolo con @Route :
@Route("hello-world") // available on /hello-world
public class HelloWorldView extends VerticalLayout {
public HelloWorldView() {
add(new H1("Hello, World!"));
}
}
Possiamo navigare tra le viste utilizzando un RouterLink :
var link = new RouterLink("Hello world view", HelloWorldView.class);
- Utilizzo degli eventi per l’interazione
Vaadin Flow è un framework event-driven. Puoi ascoltare gli eventi utente sui componenti per aggiornare l’interfaccia utente in base all’interazione dell’utente.
var nameField = new TextField("Your name");
var helloButton = new Button("Add");
helloButton.addClickListener(e -> {
Notification.show("Hello, " + nameField.getValue());
});
- Visualizzazione di oggetti Java in una griglia dati
Vaadin Flow gira sul server JVM, il che significa che abbiamo un comodo accesso ai servizi. Invece di chiamare servizi remoti dal frontend, chiamiamo i servizi come metodi Java. Diamo un’occhiata a come possiamo collegare una griglia dati a un repository Spring Data.

La griglia è supportata da una raccolta di oggetti Java. In questo esempio, utilizziamo un’entità JPA Contact definita come segue:
@Entity
public class Contact {
@Id
@GeneratedValue
private Long id;
private String name;
private String email;
private String phone;
// constructors, getters, setters
}
Possiamo quindi creare la griglia e configurare le sue colonne come segue:
var grid = new Grid<Contact>();
grid.addColumn(Contact::getName).setHeader("Name");
grid.addColumn(Contact::getEmail).setHeader("Email");
grid.addColumn(Contact::getPhone).setHeader("Phone");
Il componente Grid supporta due modi per aggiungere dati. Il caso semplice è passare un elenco di elementi in memoria:
var contacts = contactRepository.findAll();
grid.setItems(contacts);
Per set di dati più grandi, possiamo fornire alla griglia un callback che può utilizzare per caricare in modo differito i dati dal backend:
grid.setItems(query -> {
// Create a PageRequest based on page, offset, filter, sort in the query
var pageRequest = VaadinSpringDataHelpers.toSpringPageRequest(query);
return contactRepository.findAll(pageRequest).stream();
});
- Creazione di moduli e convalida dei dati
Vaadin Flow utilizza Binder per associare i campi di input a un modello di dati ed eseguire la convalida dei dati.
Costruiamo un modulo con una classe Contact definita come di seguito:
public class Contact {
@NotBlank
private String name;
@Email
private String email;
@Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}")
private String phone;
// constructors, getters, setters
}
Creiamo campi di input per ogni campo che vogliamo modificare, insieme a un pulsante per l’invio:
var nameField = new TextField("Name");
var emailField = new TextField("Email");
var phoneField = new TextField("Phone");
var saveButton = new Button("Save");
Colleghiamo i campi ai metodi getter e setter dei campi sull’oggetto dati. Definiamo le regole di convalida con asRequired() e withValidator():
binder.forField(nameField)
.asRequired()
.bind(Contact::getName, Contact::setName);
binder.forField(emailField)
.withValidator(email -> email.contains("@"), "Not a valid email address")
.bind(Contact::getEmail, Contact::setEmail);
binder.forField(phoneField)
.withValidator(phone -> phone.matches("\\d{3}-\\d{3}-\\d{4}"), "Not a valid phone number")
.bind(Contact::getPhone, Contact::setPhone);
In alternativa, Binder supporta le annotazioni Java Bean Validation tramite la sottoclasse BeanValidationBinder . Ciò ci consente di avere una convalida coerente nella nostra UI e nel backend:
var binder = new BeanValidationBinder<>(Contact.class);
binder.forField(nameField).bind(Contact::getName, Contact::setName);
binder.forField(emailField).bind(Contact::getEmail, Contact::setEmail);
binder.forField(phoneField).bind(Contact::getPhone, Contact::setPhone);
Colleghiamo il Binder al modello chiamando setBean():
var contact = new Contact("John Doe", "john@doe.com", "123-456-7890");
binder.setBean(contact);
Durante il salvataggio, verifichiamo che i valori vincolati siano validi prima di utilizzare l’oggetto salvato:
saveButton.addClickListener(e -> {
if (binder.validate().isOk()) {
Notification.show("Saved " + contact);
}
});
- Utilizzo di Server Push per gli aggiornamenti dei dati in tempo reale
Vaadin Flow supporta WebSocket per inviare aggiornamenti UI al browser. Abilita la comunicazione WebSocket aggiungendo un’annotazione @Push su una classe che estende AppShellConfigurator , in genere la classe Spring Boot Application:
@Push
@SpringBootApplication
public class Application implements AppShellConfigurator {
}
Quando si aggiorna l’interfaccia utente da un thread in background, come da un Flux nell’esempio seguente, dobbiamo usare ui.access() per garantire che Flow venga informato della modifica e possa inviarla al browser:
var output = new Span();
// Publish server time once a second
var serverTime = Flux.interval(Duration.ofSeconds(1))
.map(o -> "Server time: " + Instant.now());
serverTime.subscribe(time ->
getUI().ifPresent(ui ->
ui.access(() -> {
output.setText(time);
})
)
);
add(output);
- Costruire per la produzione
Creare un’applicazione Vaadin Flow per la produzione richiede l’utilizzo del profilo Maven di produzione . La build di produzione crea un bundle JavaScript frontend ottimizzato e disattiva il debugging in fase di sviluppo. Il profilo è incluso automaticamente nei progetti creati su Spring Initializr e Vaadin Start . Possiamo anche aggiungerlo manualmente se abbiamo un progetto personalizzato:
<profile>
<!-- Production mode is activated using -Pproduction -->
<id>production</id>
<dependencies>
<!-- Exclude development dependencies from production -->
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-core</artifactId>
<exclusions>
<exclusion>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-dev</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<executions>
<execution>
<goals>
<goal>build-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Realizziamo il progetto utilizzando il profilo di produzione eseguendo:
./mvnw package -Pproduction
- Riepilogo
In questo articolol, abbiamo appreso le basi di Vaadin Flow, un framework per la creazione di applicazioni web full-stack in Java. Include un ampio set di componenti UI e potenti funzionalità per la visualizzazione e la modifica dei dati. Poiché viene eseguito sulla JVM, possiamo accedere direttamente ai servizi backend senza la necessità di endpoint REST separati.
(fonte)
Innovaformazione, scuola informatica specialistica segue costantemente il mercato IT e promuove la formazione continua dei team di sviluppatori. Trovate l’elenco corsi per aziende informatiche sul nostro sito QUI.
INFO: info@innovaformazione.net – tel. 3471012275 (Dario Carrassi)
Articoli correlati
Claude Code per i droni
Claude Code e Migrazioni SAP
Claude Code controllo remoto
Opportunità Carriera Contabilità SAP
Guida SIA AI
