SpringBootとVaadinを使用したサンプルアプリケーション
1. 概要
Vaadin は、Webユーザーインターフェイスを作成するためのサーバー側Javaフレームワークです。
このチュートリアルでは、Spring BootベースのバックエンドでVaadinベースのUIを使用する方法について説明します。 Vaadinの概要については、thisチュートリアルを参照してください。
2. 設定
Mavenの依存関係を標準のSpring Bootアプリケーションに追加することから始めましょう。
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
Vaadinは、 SpringInitializerによって認識されている依存関係でもあります。
このチュートリアルでは、スターターモジュールによって導入されたデフォルトバージョンよりも新しいバージョンのVaadinを使用します。 新しいバージョンを使用するには、次のように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. バックエンドサービス
EmployeeエンティティとfirstNameおよびlastNameプロパティを使用して、CRUD操作を実行します。
@Entity
public class Employee {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
}
CRUD操作を管理するためのシンプルで対応するSpringDataリポジトリは次のとおりです。
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
List<Employee> findByLastNameStartsWithIgnoreCase(String lastName);
}
EmployeeRepositoryインターフェースでクエリメソッドfindByLastNameStartsWithIgnoreCaseを宣言します。 lastNameに一致するEmployeeのリストが返されます。
また、いくつかのサンプルEmployeeをDBに事前入力してみましょう。
@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. MainViewクラス
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 editor –作成および編集する従業員情報を提供するために使用されるEmployeeフォームを表示します。
グリッド
TextField filter –グリッドのフィルタリングに基づく姓を入力するテキストフィールド
Button addNewBtn –新しいEmployeeを追加するためのボタン。 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は次のようになります。
4.3. コンポーネントへのロジックの追加
ValueChangeMode.EAGERをfilterテキストフィールドに設定します。 これにより、クライアントで値が変更されるたびに、値がサーバーに同期されます。
また、値変更イベントのリスナーを設定します。このイベントは、 filter:で提供されたテキストに基づいてフィルター処理された従業員のリストを返します。
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は、Vaadins Component クラスとの競合を回避するために、Springs@Componentアノテーションの単なるエイリアスです。
@UIScope は、Beanを現在のVaadinUIにバインドします。
現在、編集されたEmployeeはemployeeメンバー変数に格納されています。 EmployeeプロパティをfirstNameおよびlastNameテキストフィールドを介してキャプチャします。
フォームには、保存、キャンセル、削除の3つのボタンがあります。
すべてのコンポーネントが相互に配線されると、行を選択するためのフォームは次のようになります。
命名規則を使用してフォームフィールドをEmployeeプロパティにバインドするBinderを使用します。
binder.bindInstanceFields(this);
ユーザー操作に基づいて、適切なEmployeeRepositorメソッドを呼び出します。
void delete() {
repository.delete(employee);
changeHandler.onChange();
}
void save() {
repository.save(employee);
changeHandler.onChange();
}
5. 結論
この記事では、永続性のためにSpringBootとSpringDataJPAを使用してフル機能のCRUDUIアプリケーションを作成しました。
いつものように、コードはGitHubでから入手できます。