Aplicativo de exemplo com Spring Boot e Vaadin
1. Visão geral
2. Configuração
Vamos começar adicionando dependências Maven a um aplicativo Spring Boot padrão:
com.vaadin
vaadin-spring-boot-starter
Vaadin também é uma dependência reconhecida peloSpring Initializer.
Este tutorial usa uma versão mais recente do Vaadin que a padrão trazida pelo módulo inicial. Para usar a versão mais recente, basta definir a Lista de materiais (BOM) do Vaadin assim:
com.vaadin
vaadin-bom
10.0.11
pom
import
3. Serviço de back-end
Usaremos uma entidadeEmployee com as propriedadesfirstNameelastName para realizar operações CRUD nela:
@Entity
public class Employee {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
}
Aqui está o repositório Spring Data simples e correspondente - para gerenciar as operações CRUD:
public interface EmployeeRepository extends JpaRepository {
List findByLastNameStartsWithIgnoreCase(String lastName);
}
Declaramos o método de consultafindByLastNameStartsWithIgnoreCase na interfaceEmployeeRepository. Ele retornará a lista deEmployees correspondendo alastName.
Vamos também preencher previamente o banco de dados com algunsEmployees de amostra:
@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. IU Vaadin
4.1. ClasseMainView
A classeMainView é o ponto de entrada para a lógica da IU do Vaadin. Annotation @Route tells Spring Boot to automatically pick it up and show at the root of the web app:
@Route
public class MainView extends VerticalLayout {
private EmployeeRepository employeeRepository;
private EmployeeEditor editor;
Grid grid;
TextField filter;
private Button addNewBtn;
}
Podemos personalizar a URL onde a visualização é mostrada, dando um parâmetro para a anotação@Route:
@Route(value="myhome")
A classe usa os seguintes componentes da interface do usuário para serem exibidos na página:
EmployeeEditor editor - mostra o formulárioEmployee usado para fornecer informações do funcionário para criar e editar.
Grid<Employee> grid - gire para exibir a lista deEmployees
TextField filter - campo de texto para inserir o sobrenome com base no qual a cinta será filtrada
Button addNewBtn - botão para adicionar um novoEmployee. Exibe o editorEmployeeEditor.
Ele usa internamente oemployeeRepository para realizar as operações CRUD.
4.2. Fiação dos componentes juntos
MainView estendeVerticalLayout. VerticalLayout is a component container, which shows the subcomponents in the order of their addition (verticalmente).
Em seguida, inicializamos e adicionamos os componentes.
Fornecemos um rótulo ao botão com um ícone +.
this.grid = new Grid<>(Employee.class);
this.filter = new TextField();
this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create());
UsamosHorizontalLayout para organizar horizontalmente o campo de texto do filtro e o botão. Em seguida, adicione este layout, gird e editor no layout vertical pai:
HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn);
add(actions, grid, editor);
Forneça a altura da cintura e os nomes das colunas. Também adicionamos texto de ajuda no campo de texto:
grid.setHeight("200px");
grid.setColumns("id", "firstName", "lastName");
grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0);
filter.setPlaceholder("Filter by last name");
Na inicialização do aplicativo, a interface do usuário ficaria assim:
4.3. Adicionando lógica aos componentes
DefiniremosValueChangeMode.EAGER para o campo de textofilter. This syncs the value to the server each time it’s changed on the client.
Também definimos um ouvinte para o evento de mudança de valor, que retorna a lista filtrada de funcionários com base no texto fornecido emfilter:
filter.setValueChangeMode(ValueChangeMode.EAGER);
filter.addValueChangeListener(e -> listEmployees(e.getValue()));
Ao selecionar uma linha dentro da cinta, mostraríamos o formulárioEmployee, permitindo ao usuário editar o nome e o sobrenome:
grid.asSingleSelect().addValueChangeListener(e -> {
editor.editEmployee(e.getValue());
});
Ao clicar no botão Adicionar novo funcionário, mostraríamos o formulárioEmployee em branco:
addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", "")));
Por fim, ouvimos as alterações feitas pelo editor e atualizamos a grade com dados do back-end:
editor.setChangeHandler(() -> {
editor.setVisible(false);
listEmployees(filter.getValue());
});
A funçãolistEmployees obtém a lista filtrada deEmployees e atualiza a grade:
void listEmployees(String filterText) {
if (StringUtils.isEmpty(filterText)) {
grid.setItems(employeeRepository.findAll());
} else {
grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText));
}
}
4.4. Criando o formulário
Usaremos um formulário simples para o usuário adicionar / editar um funcionário:
@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 binder = new Binder<>(Employee.class);
private ChangeHandler changeHandler;
}
The @SpringComponent is just an alias to Springs @Component annotation para evitar conflitos com a classe VaadinsComponent.
O@UIScope vincula o bean à IU atual do Vaadin.
Atualmente,Employee editado é armazenado na variável de membroemployee. Capturamos as propriedadesEmployee por meio dos campos de textofirstNameelastName.
O formulário tem três botões -save,canceledelete.
Depois que todos os componentes estiverem conectados, o formulário parecerá abaixo para uma seleção de linha:
Usamos umBinder which binds the form fields with the Employee properties using the naming convention:
binder.bindInstanceFields(this);
Chamamos o método EmployeeRepositor apropriado com base nas operações do usuário:
void delete() {
repository.delete(employee);
changeHandler.onChange();
}
void save() {
repository.save(employee);
changeHandler.onChange();
}
5. Conclusão
Neste artigo, escrevemos um aplicativo de interface do usuário CRUD com todos os recursos usando o Spring Boot e o Spring Data JPA para persistência.
Como de costume, o código está disponívelover on GitHub.