使用Spring Boot和Vaadin的示例应用程序

2023/05/12

1. 概述

Vaadin是用于创建 Web 用户界面的服务器端Java框架。

在本教程中,我们将探讨如何在基于Spring Boot的后端上使用基于 Vaadin 的 UI。有关 Vaadin 的介绍,请参阅 教程。

2.设置

让我们从将 Maven 依赖项添加到标准Spring Boot应用程序开始:

<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>

Vaadin 也是 Spring Initializer认可的依赖项。

本教程使用的 Vaadin 版本比 starter 模块引入的默认版本更新。要使用较新的版本,只需像这样定义 Vaadin 物料清单 (BOM):

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-bom</artifactId>
            <version>10.0.11</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

3.后台服务

我们将使用具有firstName和lastName属性的Employee实体对其执行 CRUD 操作:

@Entity
public class Employee {

    @Id
    @GeneratedValue
    private Long id;

    private String firstName;
    private String lastName;
}

这是简单的、对应的 Spring Data 存储库——用于管理 CRUD 操作:

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    List<Employee> findByLastNameStartsWithIgnoreCase(String lastName);
}

我们在EmployeeRepository接口上声明查询方法findByLastNameStartsWithIgnoreCase 。它将返回与lastName匹配的Employee列表。

我们还用一些示例Employee s预填充数据库:

@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.我需要用户界面

4.1. 主视图类

MainView类是 Vaadin 的 UI 逻辑的入口点。注解@Route告诉Spring Boot自动拾取它并显示在 Web 应用程序的根目录中:

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

我们可以通过为@Route注解提供参数来自定义显示视图的 URL:

@Route(value="myhome")

该类使用以下 UI 组件显示在页面上:

EmployeeEditor 编辑器——显示用于提供员工信息创建和编辑的Employee表单。

Grid grid – 显示员工列表的网格

TextField filter – 用于输入姓氏的文本字段,将根据其筛选 gird

按钮 addNewBtn – 添加新员工的按钮。显示EmployeeEditor编辑器。

它在内部使用employeeRepository来执行 CRUD 操作。

4.2. 将组件连接在一起

MainView扩展了VerticalLayout。VerticalLayout是一个组件容器,它按照添加的顺序(垂直)显示子组件。

接下来,我们初始化并添加组件。

我们为带有 + 图标的按钮提供标签。

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

我们使用HorizontalLayout水平排列过滤器文本字段和按钮。然后将这个布局、网格和编辑器添加到父垂直布局中:

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

提供网格高度和列名。我们还在文本字段中添加帮助文本:

grid.setHeight("200px");
grid.setColumns("id", "firstName", "lastName");
grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0);

filter.setPlaceholder("Filter by last name");

在应用程序启动时,UI 将如下所示:

桶1

4.3. 向组件添加逻辑

我们将ValueChangeMode.EAGER设置为过滤器文本字段。每次在客户端更改值时,这会将值同步到服务器。

我们还为值更改事件设置了一个侦听器,它根据过滤器中提供的文本返回过滤后的员工列表:

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

在网格中选择一行时,我们将显示Employee表单,允许用户编辑名字和姓氏:

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

单击添加新员工按钮时,我们将显示空白的员工表单:

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

最后,我们监听编辑器所做的更改,并使用来自后端的数据刷新网格:

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

listEmployees函数获取过滤后的Employee列表并更新网格:

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

4.4. 建立表格

我们将为用户使用一个简单的表单来添加/编辑员工:

@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<Employee> binder = new Binder<>(Employee.class);
    private ChangeHandler changeHandler;
}

@SpringComponent只是Springs @Component注解的别名,以避免与 Vaadins Component类发生冲突。

@UIScope将bean绑定到当前的 Vaadin UI。

目前,被编辑的Employee存储在employee成员变量中。我们通过firstName和lastName文本字段捕获Employee属性。

表单有三个按钮——保存、取消和删除。

一旦所有组件连接在一起,表格将如下所示用于行选择:

桶2

我们使用Binder,它使用命名约定将表单字段与Employee属性绑定:

binder.bindInstanceFields(this);

我们根据用户操作调用相应的 EmployeeRepositor 方法:

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

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

5.总结

在本文中,我们使用Spring Boot和 Spring Data JPA 编写了一个功能齐全的 CRUD UI 应用程序来实现持久化。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章