介绍
Vaadin的工作方式依赖于服务器端渲染,因此可以自然地集成到诸如Spring之类的框架中。 Vaadin的Spring集成已经存在了一段时间,并且提供了用于在Spring容器中配置和管理Vaadin的工具,如果您希望将Vaadin与Spring Boot结合使用,那么您会很幸运,因为Vaadin的人已经做了创建可以自动配置几乎所有内容的启动程序的工作,以便您可以在几秒钟内启动并运行一个简单的UI。 在本文中,我们将简要介绍如何在Spring boot中使用Vaadin。
设定
创建Spring引导应用程序的最佳方法是使用Spring Initializr 。 我们将检查Vaadin以及其他标准的Spring起动器,例如Web和Security,然后单击“ Generate Project”。
要在上下文路径的根部创建视图,只需创建一个扩展UI
的类并使用@SpringUI
进行批注就@SpringUI
。
@SpringUI
public class Main extends UI {
@Override
protected void init(VaadinRequest vaadinRequest) {
setContent(new Label("Hello"));
}
}
如果要使用的路径与根目录不同,则可以使用path属性: @SpringUI(path="/app")
。
用户界面和视图
Vaadin的用户界面概念类似于SPA(单页应用程序)的概念。 UI
类被视为多个视图的根容器。 视图可以看作是UI的特定状态。 一个应用程序可以具有多个UI
类,但是建议使用一个具有多个视图的UI
,因为它效率更高。 借助Navigator
,可以在不离开页面或UI
情况下从一个视图配置到另一个视图。 要创建一个View
,我们只需要实现视图接口并用@SpringView
对其进行注释,或者如果范围(我们将在以后讨论视图范围)不是很重要,那么任何Spring注入注释都可以工作:
@SpringView
public class Add extends Composite implements View {
@PostConstruct
public void init() {
setCompositionRoot(new Label("I am a view"));
}
}
我们在这里使用了带有@PostConstruct
的init()
方法,以确保Spring已完成注入任何字段(如果有的话)。 如果没有注入的字段,也可以使用构造函数。
例
Vaadin是一个完全成熟的框架,具有开发人员可以选择的多种组件 (布局,图表,网格..)。 它还提供了创建自定义组件的可能性。 例如,我们要创建一个汽车收集应用程序,以允许输入和列出汽车模型:
添加视图:
@SpringView
public class Add extends Composite implements View {
@Autowired
CarRepository repository;
@Autowired
DataProvider dataProvider;
@PostConstruct
public void init() {
FormLayout formLayout = new FormLayout();
Label title = new Label("Add new Car");
TextField brandInput = new TextField("Brand: ");
TextField modelInput = new TextField("Model: ");
TextField pictureLinkInput = new TextField("Picture Link: ");
Button button = new Button("Add", clickEvent -> {
repository.save(new Car(brandInput.getValue(), modelInput.getValue(), pictureLinkInput.getValue()));
Notification.show("saved");
});
formLayout.addComponent(title);
formLayout.addComponent(brandInput);
formLayout.addComponent(modelInput);
formLayout.addComponent(pictureLinkInput);
formLayout.addComponent(button);
setCompositionRoot(formLayout);
}
}
列表视图:
@SpringView
public class List extends Composite implements View {
@Autowired
CarRepository repository;
@Autowired
DataProvider dataProvider;
@PostConstruct
public void init() {
Grid<Car> carGrid = new Grid<>();
carGrid.setWidth("100%");
carGrid.setHeight("100%");
carGrid.setDataProvider(dataProvider);
carGrid.addColumn(Car::getId).setCaption("Id");
carGrid.addColumn(Car::getBrand).setCaption("Brand");
carGrid.addColumn(Car::getModel).setCaption("Model");
carGrid.addColumn((ValueProvider<Car, Object>) car ->
new ExternalResource(car.getPictureLink())).setCaption("Picture")
.setRenderer(new ImageRenderer()).setResizable(true);
setCompositionRoot(carGrid);
setSizeFull();
}
}
主界面:
@SpringUI(path="app")
@StyleSheet({"http://localhost:8080/styles.css"})
public class Main extends UI {
@Autowired
Add addView;
@Autowired
List listView;
@Override
protected void init(VaadinRequest vaadinRequest) {
HorizontalLayout rootLayout = new HorizontalLayout();
rootLayout.setSizeFull();
HorizontalLayout mainarea = new HorizontalLayout();
mainarea.setWidth("80%");
Navigator navigator = new Navigator(this, mainarea);
navigator.addView("", addView);
navigator.addView("add", addView);
navigator.addView("list", listView);
CssLayout sideNav = new CssLayout();
sideNav.setSizeFull();
sideNav.addStyleName("sidenav");
sideNav.setId("sideNav");
sideNav.setWidth("20%");
Button link1 = new Button("Add", e -> navigator.navigateTo("add"));
link1.addStyleNames(BUTTON_LINK, MENU_ITEM);
Button link2 = new Button("List", e -> navigator.navigateTo("list"));
link2.addStyleNames(BUTTON_LINK, MENU_ITEM);
sideNav.addComponent(link1);
sideNav.addComponent(link2);
rootLayout.addComponent(sideNav);
rootLayout.addComponent(mainarea);
setContent(rootLayout);
}
}
我们创建了两个视图:一个用于添加汽车的表单和一个用于显示汽车的网格。 UI类使用navigator
将两个视图连接起来。 用户界面由两部分组成:侧面导航栏(带有指向视图的链接)和主要区域(可变部分)。 我们已经将navigator
配置为仅在主区域中调度视图,并配置了前往每个视图的路由:
Navigator navigator = new Navigator(this, mainarea);
navigator.addView("", addView);
navigator.addView("add", addView);
navigator.addView("list", listView);
拥有默认的""
空路由很重要,因为通常在启动时未设置该路由。 由于Vaadin使用自己的主题和样式表,因此@StyleSheet
批注会很方便地引入自定义样式。 我们的视图和UI已连接到Spring容器,因此可以注入任何Spring bean。 例如,我们注入了CarRepository
,它是一个JpaRepository
用于对Car
实体执行数据库操作。
安全
Vaadin使用自己的CSRF令牌,因此,如果使用Spring Security,则应禁用Spring CSRF机制以使应用程序正常运行。 最低安全配置如下所示:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/app**").authenticated().and().formLogin().and().csrf().disable();
}
}
包起来
Vaadin可以看作是使用Spring Boot后端快速创建UI的替代方法。 Vaadin一开始可能很容易建立,但是当复杂度增加时,学习曲线似乎并不那么平滑。 使用Vaadin(不仅使用Spring)时可能会注意到的另一个缺点是,每次进行更改时都必须重新启动整个应用程序(通常需要一段时间才能启动Spring Container),这导致需要设置HotSwap
或类似的工具,无需重新启动应用程序即可热重载代码。
翻译自: https://www.javacodegeeks.com/2018/05/introduction-to-using-vaadin-in-spring-boot.html