Spring Boot集成vaadin快速入门demo

1.什么是vaadin?

Vaadin 是用于构建单页 Web 应用的流行 Java 框架。 它由一家专门从事富 Internet 应用设计和开发的芬兰公司开发。 估计有 15 万开发者使用 Vaadin。 它的开发始于 2002 年。

Vaadin 框架特性

 

以下是 Vaadin 特性的列表:

  • 这是一个 Java Web 框架

  • 概念上类似于 Java Swing

  • 允许构建不带 HTML 和 JavaScript 的 Web 应用

  • 基于 Java Servlet 构建

  • 包含大量组件和窗口

  • 提供可定制的外观

  • 在客户端和服务器之间使用异步消息

  • 使用服务器端编程模型

  • 具有 Eclipse,NetBeans 和 IntelliJ 的插件

  • 使用 Google Web Toolkit 呈现结果网页

  • 提升代码质量和安全性

2.代码工程

实验目标

用嵌入式数据库h2存储数据,用vaadin构建crud操作界面,使用jpa操作h2数据库

pom.xml

<?xml version="1.0" encoding="UTF-8"?><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>

view

主视图类(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 layout HorizontalLayout 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 filter filter.setValueChangeMode(ValueChangeMode.LAZY); filter.addValueChangeListener(e -> listCustomers(e.getValue()));
// Connect selected Customer to editor or hide if none is selected grid.asSingleSelect().addValueChangeListener(e -> { editor.editCustomer(e.getValue()); });
// Instantiate and edit new Customer the new button is clicked addNewBtn.addClickListener(e -> editor.editCustomer(new Customer("", "")));
// Listen changes made by the editor, refresh data from backend editor.setChangeHandler(() -> { editor.setVisible(false); listCustomers(filter.getValue()); });
// Initialize listing listCustomers(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 layout HorizontalLayout 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 filter filter.setValueChangeMode(ValueChangeMode.LAZY); filter.addValueChangeListener(e -> listCustomers(e.getValue()));
// Connect selected Customer to editor or hide if none is selected grid.asSingleSelect().addValueChangeListener(e -> { editor.editCustomer(e.getValue()); });
// Instantiate and edit new Customer the new button is clicked addNewBtn.addClickListener(e -> editor.editCustomer(new Customer("", "")));
// Listen changes made by the editor, refresh data from backend editor.setChangeHandler(() -> { editor.setVisible(false); listCustomers(filter.getValue()); });
// Initialize listing listCustomers(null); }
// tag::listCustomers[] void listCustomers(String filterText) { if (StringUtils.hasText(filterText)) { grid.setItems(repo.findByLastNameStartsWithIgnoreCase(filterText)); } else { grid.setItems(repo.findAll()); } } // end::listCustomers[]
}

entity

package com.et.vaadin.entity;
import jakarta.persistence.Entity;import jakarta.persistence.GeneratedValue;import jakarta.persistence.Id;
@Entitypublic class Customer {
@Id @GeneratedValue 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; }
@Override public String toString() { return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName); }
}

repository

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

application.yaml

server:  port: 8088

DemoApplication.java

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;
@SpringBootApplication
public class DemoApplication { private static final Logger log = LoggerFactory.getLogger(DemoApplication.class);
public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Bean public CommandLineRunner loadData(CustomerRepository repository) { return (args) -> { // save a couple of customers repository.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 customers log.info("Customers found with findAll():"); log.info("-------------------------------"); for (Customer customer : repository.findAll()) { log.info(customer.toString()); } log.info("");
// fetch an individual customer by ID Customer customer = repository.findById(1L).get(); log.info("Customer found with findOne(1L):"); log.info("--------------------------------"); log.info(customer.toString()); log.info("");
// fetch customers by last name log.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

3.测试

启动Spring Boot应用,

测试crud操作

访问地址http://127.0.0.1:8088/

 

4.引用

  • https://vaadin.com/docs/v14/flow/tutorial/overview

  • http://www.liuhaihua.cn/archives/710719.html

相关推荐

  • 全网最佳websocket封装:完美支持断网重连、自动心跳!
  • 实用技巧,用lsof命令监控tar文件解压进度,简单有效!
  • 10个非常炫酷的 JavaScript 动画库!!!
  • 同事给我介绍了个私活儿,说1万报酬全给我,昨天快要交片之前,我私下问了下甲方,结果甲方说你同事白拿了很多。
  • 超简单下载网站视频,两个日常生活中极为实用的开源高星项目
  • Logback 与 log4j2 性能哪个更强?
  • CVPR 2024满分论文出炉!这些方向杀疯了!
  • 本科生连发两篇AI顶会后,再发大模型顶刊!
  • 一文吃透Transformer代码与应用【附226篇顶会论文】
  • APP如何与H5通信?
  • 超火超实用的 10 个前端工具库,可能就是你一直在寻找的~
  • AI浪潮,Spring也赶上了!?
  • 盘点历届 Java 语言的关键字,一定有你不认识的
  • 用 Lag-Llama 进行时间序列预测实战
  • 这算是裁到大动脉了吧
  • [开源]轻松构建车联网平台,可应用于各种车辆监管场景和应用平台
  • Kubernetes新手必看:快速生成YAML清单的终极指南!
  • 记一次疑似JVM内存泄漏的排查过程
  • 高中信息技术考试竟然有Flash、IIS、Frontpage、Access、VB……
  • 带您认识物联网首选协议MQTT