Vaadin 是用于构建单页 Web 应用的流行 Java 框架。 它由一家专门从事富 Internet 应用设计和开发的芬兰公司开发。 估计有 15 万开发者使用 Vaadin。 它的开发始于 2002 年。
以下是 Vaadin 特性的列表:
这是一个 Java Web 框架
概念上类似于 Java Swing
允许构建不带 HTML 和 JavaScript 的 Web 应用
基于 Java Servlet 构建
包含大量组件和窗口
提供可定制的外观
在客户端和服务器之间使用异步消息
使用服务器端编程模型
具有 Eclipse,NetBeans 和 IntelliJ 的插件
使用 Google Web Toolkit 呈现结果网页
提升代码质量和安全性
用嵌入式数据库h2存储数据,用vaadin构建crud操作界面,使用jpa操作h2数据库
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.0</version><relativePath/><!-- lookup parent from repository --></parent><modelVersion>4.0.0</modelVersion><artifactId>vaadin</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><vaadin.version>24.3.13</vaadin.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>com.vaadin</groupId><artifactId>vaadin-spring-boot-starter</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>com.vaadin</groupId><artifactId>vaadin-bom</artifactId><version>24.3.8</version> <!-- check latest version --><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>
主视图类(MainView本指南中称为)是 Vaadin 的 UI 逻辑的入口点。在 Spring Boot 应用程序中,如果您使用 对其进行注释@Route,它将自动被拾取并显示在 Web 应用程序的根目录中。您可以通过为注释提供参数来自定义显示视图的 URL @Route
package com.et.vaadin.view;import com.et.vaadin.entity.Customer;import com.et.vaadin.repository.CustomerRepository;import com.vaadin.flow.component.button.Button;import com.vaadin.flow.component.grid.Grid;import com.vaadin.flow.component.icon.VaadinIcon;import com.vaadin.flow.component.orderedlayout.HorizontalLayout;import com.vaadin.flow.component.orderedlayout.VerticalLayout;import com.vaadin.flow.component.textfield.TextField;import com.vaadin.flow.data.value.ValueChangeMode;import com.vaadin.flow.router.Route;import org.springframework.util.StringUtils;@Routepublic class MainView extends VerticalLayout {private final CustomerRepository repo;private final CustomerEditor editor;final Grid<Customer> grid;final TextField filter;private final Button addNewBtn;public MainView(CustomerRepository repo, CustomerEditor editor) {this.repo = repo;this.editor = editor;this.grid = new Grid<>(Customer.class);this.filter = new TextField();this.addNewBtn = new Button("New customer", VaadinIcon.PLUS.create());// build layoutHorizontalLayout actions = new HorizontalLayout(filter, addNewBtn);add(actions, grid, editor);grid.setHeight("300px");grid.setColumns("id", "firstName", "lastName");grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0);filter.setPlaceholder("Filter by last name");// Hook logic to components// Replace listing with filtered content when user changes filterfilter.setValueChangeMode(ValueChangeMode.LAZY);filter.addValueChangeListener(e -> listCustomers(e.getValue()));// Connect selected Customer to editor or hide if none is selectedgrid.asSingleSelect().addValueChangeListener(e -> {editor.editCustomer(e.getValue());});// Instantiate and edit new Customer the new button is clickedaddNewBtn.addClickListener(e -> editor.editCustomer(new Customer("", "")));// Listen changes made by the editor, refresh data from backendeditor.setChangeHandler(() -> {editor.setVisible(false);listCustomers(filter.getValue());});// Initialize listinglistCustomers(null);}// tag::listCustomers[]void listCustomers(String filterText) {if (StringUtils.hasText(filterText)) {grid.setItems(repo.findByLastNameStartsWithIgnoreCase(filterText));} else {grid.setItems(repo.findAll());}}// end::listCustomers[]}
由于 Vaadin UI 是纯 Java 代码,因此您可以从头开始编写可重复使用的代码。为此,请为您的Customer实体定义一个编辑器组件。您可以将其设为 Spring 管理的 bean,以便您可以直接将其注入CustomerRepository编辑器并处理创建、更新和删除部分或您的 CRUD 功能
package com.et.vaadin.view;import com.et.vaadin.entity.Customer;import com.et.vaadin.repository.CustomerRepository;import com.vaadin.flow.component.button.Button;import com.vaadin.flow.component.grid.Grid;import com.vaadin.flow.component.icon.VaadinIcon;import com.vaadin.flow.component.orderedlayout.HorizontalLayout;import com.vaadin.flow.component.orderedlayout.VerticalLayout;import com.vaadin.flow.component.textfield.TextField;import com.vaadin.flow.data.value.ValueChangeMode;import com.vaadin.flow.router.Route;import org.springframework.util.StringUtils;@Routepublic class MainView extends VerticalLayout {private final CustomerRepository repo;private final CustomerEditor editor;final Grid<Customer> grid;final TextField filter;private final Button addNewBtn;public MainView(CustomerRepository repo, CustomerEditor editor) {this.repo = repo;this.editor = editor;this.grid = new Grid<>(Customer.class);this.filter = new TextField();this.addNewBtn = new Button("New customer", VaadinIcon.PLUS.create());// build layoutHorizontalLayout actions = new HorizontalLayout(filter, addNewBtn);add(actions, grid, editor);grid.setHeight("300px");grid.setColumns("id", "firstName", "lastName");grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0);filter.setPlaceholder("Filter by last name");// Hook logic to components// Replace listing with filtered content when user changes filterfilter.setValueChangeMode(ValueChangeMode.LAZY);filter.addValueChangeListener(e -> listCustomers(e.getValue()));// Connect selected Customer to editor or hide if none is selectedgrid.asSingleSelect().addValueChangeListener(e -> {editor.editCustomer(e.getValue());});// Instantiate and edit new Customer the new button is clickedaddNewBtn.addClickListener(e -> editor.editCustomer(new Customer("", "")));// Listen changes made by the editor, refresh data from backendeditor.setChangeHandler(() -> {editor.setVisible(false);listCustomers(filter.getValue());});// Initialize listinglistCustomers(null);}// tag::listCustomers[]void listCustomers(String filterText) {if (StringUtils.hasText(filterText)) {grid.setItems(repo.findByLastNameStartsWithIgnoreCase(filterText));} else {grid.setItems(repo.findAll());}}// end::listCustomers[]}
package com.et.vaadin.entity;import jakarta.persistence.Entity;import jakarta.persistence.GeneratedValue;import jakarta.persistence.Id;public class Customer {private Long id;private String firstName;private String lastName;protected Customer() {}public Customer(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}public Long getId() {return id;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String toString() {return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id,firstName, lastName);}}
package com.et.vaadin.repository;import com.et.vaadin.entity.Customer;import org.springframework.data.jpa.repository.JpaRepository;import java.util.List;/*** @author liuhaihua* @version 1.0* @ClassName CustomerRepository* @Description todo*/public interface CustomerRepository extends JpaRepository<Customer, Long> {List<Customer> findByLastNameStartsWithIgnoreCase(String lastName);}
server:port: 8088
package com.et.vaadin;import com.et.vaadin.entity.Customer;import com.et.vaadin.repository.CustomerRepository;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.CommandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;@SpringBootApplicationpublic class DemoApplication {private static final Logger log = LoggerFactory.getLogger(DemoApplication.class);public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Beanpublic CommandLineRunner loadData(CustomerRepository repository) {return (args) -> {// save a couple of customersrepository.save(new Customer("Jack", "Bauer"));repository.save(new Customer("Chloe", "O'Brian"));repository.save(new Customer("Kim", "Bauer"));repository.save(new Customer("David", "Palmer"));repository.save(new Customer("Michelle", "Dessler"));// fetch all customerslog.info("Customers found with findAll():");log.info("-------------------------------");for (Customer customer : repository.findAll()) {log.info(customer.toString());}log.info("");// fetch an individual customer by IDCustomer customer = repository.findById(1L).get();log.info("Customer found with findOne(1L):");log.info("--------------------------------");log.info(customer.toString());log.info("");// fetch customers by last namelog.info("Customer found with findByLastNameStartsWithIgnoreCase('Bauer'):");log.info("--------------------------------------------");for (Customer bauer : repository.findByLastNameStartsWithIgnoreCase("Bauer")) {log.info(bauer.toString());}log.info("");};}}
以上只是一些关键代码,所有代码请参见下面代码仓库
https://github.com/Harries/springboot-demo
启动Spring Boot应用,
访问地址http://127.0.0.1:8088/
https://vaadin.com/docs/v14/flow/tutorial/overview
http://www.liuhaihua.cn/archives/710719.html
原文作者:HBLOG;如有侵权,请联系管理员删除。