显示导航

365bet地区使用Vaadin框架构建365bet地区应用程序

365bet地区了解如何使用Vaadin框架构建365bet地区应用程序

本·莱茵

365bet地区版本 3.3.1

365bet地区培训

365bet地区培训由创建并积极维护365bet地区框架的人们开发和交付

入门

365bet地区在本指南中,您将使用Vaadin框架构建365bet地区应用程序

您将需要什么

要完成本指南,您将需要以下内容

  • 花些时间在你手上

  • 体面的文本编辑器或IDE

  • 安装了JDK或更高版本JAVA首页适当配置

如何完成指南

要开始,请执行以下操作

要么

365bet地区指南存储库包含两个文件夹

  • 初始初始项目通常是一个简单的365bet地区应用程序,其中包含一些其他代码,可以帮助您快速入门

  • 完成一个完整的示例它是按照指南中介绍的步骤进行操作并将这些更改应用于文档的结果。初始

要完成指南,请转到初始

  • 光盘进入365bet地区引导视图365bet地区初始

您可以直接前往如果你光盘进入365bet地区指南看起来365bet地区完整

365bet地区看365bet地区的个人资料

初始使用以下命令创建了该项目的目录

365bet地区为przepiora查看器创建应用演示配置文件365bet地区 Web查看器

我们提供给创建应用命令看365bet地区的个人资料s坐标

随着使用应用资料365bet地区365bet地区允许您构建现代的Web应用程序有一些配置文件可促进使用Javascript前端Angular REACT或Vaadin应用程序构建REST API或Web应用程序

关于我在找

我的需求是用于业务应用程序的Java Web UI框架

使用Vaadin Framework,您将使用熟悉的基于组件的方法比使用任何其他UI框架更快地构建出色的单页Web应用程序。

手机和桌面上的图表
365bet地区Vaadin 365bet地区配置文件允许您混合使用Vaadin端点和传统365bet地区端点

365bet地区一方面,我们将拥有由365bet地区控制器处理的端点,它们将使用以下方式呈现HTML JSON或XML:普遍优惠制要么365bet地区365bet地区视图.

365bet地区另一方面,我们将拥有Vaadin端点。我们将使用Java或Groovy开发UI,并将直接连接到365bet地区服务层

如果您需要有关Vaadin的其他信息,请查阅官方文档这里此外,在较旧版本的Vaadin和这个该页面很好地说明了Vaadin中如何更新其中一些功能

运行应用程序

此时建议进行一次测试,以确保一切正常

首先运行应用程序

cd首字母

要启动应用程序,请运行以下命令

gradlew bootRun

365bet地区如果一切顺利,这将启动365bet地区应用程序,该应用程序将在HTTP本地主机

grails默认

为此,我在行动中导航到http localhost vaadinUI代替

vaadinDefault

编写申请

创建域

让我们从为应用程序创建域模型开始

grails创建域类演示驱动程序grails创建域类演示Make grails创建域类演示Model grails创建域类演示User grails创建域类演示Vehicle

现在让我们在grails应用程序域演示下编辑域类。我们将添加一些属性和以下三个注释

  • 标有的代码365bet地区365bet地区CompileStatic365bet地区除了不能静态编译的365bet地区特定交互,所有365bet地区都将被静态编译,而365bet地区CompileStatic可以将其标识为允许进行动态调度,这些交互包括在配置块中调用动态查找器和DSL代码,例如约束和域类中的映射闭包

  • EqualsAndHashCode自动生成equals和hashCode方法

  • ToString自动生成toString方法

grails应用程序域演示轻松搞定
演示进口 grails编译器365bet地区CompileStatic
进口 常规转换EqualsAndHashCode
进口 常规转换ToString


EqualsAndHashCode包括'那么'])
ToString包括'那么'includeNames真正includePackage)
 使 {

    那么静态的约束名称可为空: 
    }
}
grails应用程序域演示模型groovy
演示进口 grails编译器365bet地区CompileStatic
进口 常规转换EqualsAndHashCode
进口 常规转换ToString


EqualsAndHashCode包括'那么'])
ToString包括'那么'includeNames真正includePackage)
 模型 {

    那么静态的约束名称可为空: 
    }
}
grails应用程序域演示Vehicle Groovy
演示进口 grails编译器365bet地区CompileStatic
进口 常规转换EqualsAndHashCode
进口 常规转换ToString


EqualsAndHashCode包括'那么', '使', '模型'])
ToString包括'那么', '使', '模型'includeNames真正includePackage)
 车辆 {
    名称制作型号模型静态的属于司机: 司机]

    静态的映射名称可为空: 
    }

    静态的约束

我们还有更多驱动程序比头等舱要好得多这是因为我们实际上正在扩展我们的用户习惯带驱动程序的类这将在将来扩展应用程序时为我们提供更多的灵活性

grails应用程序域演示驱动程序groovy
演示进口 grails编译器365bet地区CompileStatic
进口 常规转换EqualsAndHashCode
进口 常规转换ToString


EqualsAndHashCode包括'那么'])
ToString包括'那么'includeNames真正includePackage)
 司机 延伸用户那么静态的有很多车辆静态的约束车辆可为空: 真正
    }
}
grails应用程序域演示用户groovy
演示进口 常规转换EqualsAndHashCode
进口 常规转换ToString
进口 grails编译器365bet地区CompileStatic


EqualsAndHashCode包括'用户名')
ToString包括'用户名'includeNames真正includePackage)
 用户 实施 可序列化 {
    私人的 静态的 最后 serialVersionUID1

    用户名密码布尔值已启用真正
    布尔值accountExpired布尔值帐户被锁定布尔值密码已过期静态的约束密码可为空: , 空白: , 密码: 真正用户名可为空: , 空白: , : 真正
    }

    静态的映射密码: '密码'
    }
}

引导数据

现在我们的域已经到位,可以预加载一些数据以进行处理

365bet地区应用程序初始化演示BootStrap groovy
演示进口 groovy util日志记录Slf j

自我
 引导带 {

    定义初始化servletContext日志信息"载入资料库"
        最后司机 司机(那么: "苏珊", 用户名: "苏珊", 密码: "密码"保存最后司机 司机(那么: "彼得", 用户名:  "彼得", 密码: "密码"保存最后日产使那么: "日产"保存最后福特汽车使那么: "福特汽车"保存最后体坛模型那么: "Titan"保存最后模型那么: ""保存最后风星模型那么: "风星"保存车辆那么: "拾起", 司机司机使日产模型泰坦保存车辆那么: "经济", 司机司机使日产模型叶保存车辆那么: "小型货车", 司机司机使福特汽车模型风之星保存定义破坏

创建服务层

365bet地区接下来,让我们为应用程序创建服务层,以便365bet地区和Vaadin可以共享资源

创建服务演示DriverService创建服务演示MakeService创建服务演示ModelService创建服务演示VehicleService

现在让我们在grails应用程序服务演示下编辑我们的服务类。listAll所有类的方法此方法将具有以下附加注释

  • 只读关于仅返回数据的方法的良好实践

grails应用服务演示DriverService groovy
演示进口 grails gorm交易ReadOnly
进口 常规转换CompileStatic

静态编译
只读
 司机服务 {

    只读
    清单<司机listAll司机清单
grails应用服务演示MakeService groovy
演示进口 grails gorm交易ReadOnly
进口 常规转换CompileStatic

静态编译
 MakeService {

    只读
    清单listAll在哪里列出
grails应用服务演示ModelService groovy
演示进口 grails gorm交易ReadOnly
进口 常规转换CompileStatic

静态编译
 模型服务 {

    只读
    清单listAll型号清单

我们的VehicleService常规还有一个保存方法,以便我们可以向应用程序中添加新数据

365bet地区应用服务演示VehicleService groovy
演示进口 grails gorm交易ReadOnly
进口 常规转换CompileStatic

静态编译
只读
 车辆服务 {

    定义 保存(最后车辆车辆保存failOnError: 真正)
    }

    只读
    清单listAll布尔值懒惰的真正) {
        如果懒惰的返回车辆在哪里加入'使'加入'模型'加入'司机'清单车辆清单

创建一个控制器

365bet地区尽管对于Vaadin而言完全不必要,但我们想证明365bet地区控制器与Vaadin框架之间没有冲突

grails创建控制器演示GarageController

现在,让我们在grails应用程序控制器演示下编辑控制器。我们将导入我们的一项服务,以更新索引方法并添加以下注释

  • 标有的代码365bet地区CompileStatic除了不能静态编译的365bet地区特定交互,所有365bet地区都将被静态编译,而365bet地区CompileStatic可以将其标识为允许进行动态调度,这些交互包括在配置块中调用动态查找器和DSL代码,例如约束和域类中的映射闭包

365bet地区应用控制器演示GarageController groovy
演示进口 grails转换器JSON
进口 常规转换CompileStatic

静态编译
 车库控制器车辆服务车辆服务(1)

    定义 指数() { (2)
        最后 清单vehicleList车辆服务清单所有渲染的VehicleListJSON格式
1 宣布我们的服务
2 指数调用我们的服务并将输出呈现为JSON

此时,请确保一切正常并运行运行App应用程序

现在我们可以使用cURL或其他API工具来练习API

向车库发出GET请求以获取车辆清单

curl X GET http localhost车库ID驱动程序ID制造ID模型ID名称皮卡ID驱动程序ID制造ID模型ID名称经济ID驱动程序ID制造ID模型ID名称小型货车

365bet地区如果数据返回,则此时一切均已设置并正确连接,并且我们已经验证了一些测试数据,现在让我们看看如何将Vaadin附加到365bet地区

我的需求

最后时间开始将Vaadin代码添加到我们的应用程序中

考虑365bet地区src main groovy演示Demo365bet地区UI groovy成为您的Vaadin控制器调度员,因为它将帮助您了解Vaadin流程在里面方法是Vaadin本身的应用程序入口点,这实际上是您的顶级视图。从这里,您可以设置导航和其他整个应用程序视图组件

我们的365bet地区Demo365bet地区UI groovy因为它当前对于单页Web应用程序非常有用,但是如果我们以后要添加导航组件或其他页面,它并不是最灵活的。考虑到这一点,我们将使用视图使它更加灵活。有助于保持Vaadin前端井井有条

有关使用Vaadin的视图和导航的更多信息,请参见这里.
src main groovy演示Demo365bet地区UI groovy
演示进口 COM,我需要注释标题
进口 COM,我需要导航器视图
进口 com我需要导航器ViewDisplay
进口 COM我寻找服务器LookinRequest
进口 COM我需要注释主题
进口 com我需要spring注释SpringUI
进口 com我需要弹簧注释SpringViewDisplay
进口 com我需要ui组件
进口 COM,我需要ui标签
进口 COM,我需要ui面板
进口 com我需要ui ui
进口 COM我需要UI VerticalLayout
进口 常规转换CompileStatic

静态编译
SpringUI路径"vaadinUI")
标题("365bet地区看365bet地区") (1)
春天视图显示 (2)
 365bet地区Demo365bet地区UI 延伸洋葱实施ViewDisplay(3)
    私人的 面板弹簧取景显示(4)

    线条很重要时,它可以更改元素的位置
    覆写
    受保护的 虚空初始化Vaadin请求请求(5)
        最后VerticalLayout根VerticalLayout根setSizeFull setContent根springViewDisplay 面板springViewDisplay setSizeFull root addComponent buildHeader root addComponent springViewDisplay root setExpandRatio springViewDisplayF)
    }

    静态的 私人的 标签buildHeader(6)
        最后 标签mainTitle 标签("欢迎来到车库"mainTitle覆写
    虚空showView最后 视图视图(7)springViewDisplay setContent零件视图
1 我们添加标题批注为我们的窗口选项卡起了一个好名字
2 春天视图显示这样我们就可以使用视图
3 与和实现ViewDisplay到我们班上
4 接下来为我们的用户界面创建一个附加面板
5 Vaadin视图的初始入口点
6 建立标头的辅助方法
7 使用视图所需的附加功能可动态控制设置视图组件
将组件添加到布局的顺序可以确定它们在布局中的位置
在里面可以很快变得很大,因此最好将UI组件分解为自己的方法,例如buildHeader使您的文件清晰明了

添加您的视图

现在添加视图,这是我们Vaadin代码的大部分内容。src main groovy演示GarageView groovy.

接下来进行必要的更新

src main groovy演示GarageView groovy
演示进口 com我需要HasValue中的数据
进口 com我需要ValueProvider的数据
进口 com我需要事件选择SelectionEvent
进口 COM我需要事件选择SelectionListener
进口 COM我需要事件选择SingleSelectionEvent
进口 COM我需要事件选择SingleSelectionListener
进口 COM,我需要导航器视图
进口 com我在寻找Navigator ViewChangeListener
进口 COM我需要弹簧注释SpringView
进口 COM,我需要ui按钮
进口 COM,我需要ui ComboBox
进口 com我需要ui网格
进口 COM我需要UI Horizo​​ntalLayout
进口 COM我需要UI ItemCaptionGenerator
进口 COM,我需要ui标签
进口 COM我需要UI TextField
进口 COM我需要UI VerticalLayout
进口 groovy util日志记录Slf j
进口 org springframework bean工厂注释自动装配
进口 javax注释PostConstruct
进口 常规转换CompileStatic

自我
静态编译
SpringView名称GarageView VIEW NAME(1)
 车库视图 延伸垂直布局实施 视图 { (2)
    上市 静态的 最后 查看名称"" (3)

    自动接线  (4)
    私人的DriverService driverService自动接线
    私人的MakeService makeService自动接线

    私人的ModelService modelService自动接线
    私人的车辆服务车辆服务私人的车辆车辆后构造 (5)
    虚空在里面显示第一行添加面板标题
        最后Horizo​​ntalLayout标题行Horizo​​ntalLayout标题行setWidth"100%"addComponent titleRow最后 标签标题 标签("添加车辆"titleRow addComponent标题titleRow setExpandRatio标题F) 扩大

        显示第二行构建数据输入
        最后Horizo​​ntalLayout输入行Horizo​​ntalLayout输入行setWidth"100%"addComponent inputRow建立数据输入构造
        最后 文本域车辆名称这个buildNewVehicleName最后组合框车辆制造这个buildMakeComponent最后组合框车辆型号这个buildModelComponent最后组合框司机vehicleDriver这个buildDriverComponent最后 纽扣SubmitBtn这个buildSubmitButton添加侦听器以捕获数据更改
        标签侦听器vehicleName addValueChangeListenerUpdateVehicleValueChangeListener'name'vehicleMake addSelectionListenerUpdateVehicleComboBoxSelectionLister'使'vehicleModel addSelectionListenerUpdateVehicleComboBoxSelectionLister'模型'vehicleDriver addSelectionListenerUpdateVehicleComboBoxSelectionLister'驱动器'SubmitBtn addClickListener事件这个提交最终听众

        将数据构造添加到行vehicleName vehicleMake vehicleModel vehicleDriver SubmitBtn每个输入行addComponent)
        }

        显示第三行显示数据库中的所有车辆
        最后Horizo​​ntalLayout dataDisplayRowHorizo​​ntalLayout dataDisplayRow setWidth"100%"addComponent dataDisplayRow dataDisplayRow addComponent这个buildVehicleComponent UpdateVehicleValueChangeListener 实施HasValue ValueChangeListenereventType UpdateVehicleValueChangeListener事件类型这个eventType eventType覆写
        虚空valueChange HasValue ValueChangeEvent事件updateVehicle eventType事件值 UpdateVehicleComboBoxSelectionLister 实施SingleSelectionListenereventType UpdateVehicleComboBoxSelectionLister事件类型这个eventType eventType覆写
        虚空selectionChange SingleSelectionEvent事件updateVehicle eventType事件firstSelectedItem覆写
    虚空输入ViewChangeListener ViewChangeEvent事件该视图是在init方法中构造的
    }

    私有UI组件构建器
    静态的 私人的 文本域buildNewVehicleName最后 文本域车辆名称 文本域vehicleName setPlaceholder"输入名字"车辆名称私人的组合框buildMakeComponent最后 清单使makeService listAll最后组合框选择组合框选择setEmptySelectionAllowed选择setPlaceholder"选择一个品牌"选择setItemCaptionGeneratorCustomItemCaptionGenerator select setItems使选择 CustomItemCaptionGenerator 实施ItemCaptionGenerator覆写
        应用宾语项目如果项目实例使返回项目命名如果项目实例 司机 ) {
                返回项目 司机那么如果项目实例模型返回项目型号名称空值
        }
    }

    私人的组合框buildModelComponent最后 清单型号modelService listAl最后组合框选择组合框选择setEmptySelectionAllowed选择setPlaceholder"选择型号"选择setItemCaptionGeneratorCustomItemCaptionGenerator选择setItems模型选择私人的组合框司机buildDriverComponent最后 清单<司机驱动程序driver服务列表全部最后组合框司机选择组合框选择setEmptySelectionAllowed选择setPlaceholder"选择一个驱动程序"选择setItemCaptionGeneratorCustomItemCaptionGenerator选择setItems驱动程序选择私人的网格buildVehicleComponent最后 清单车辆车辆服务清单全部) (6)
        最后格网网格网格setSizeFull确保网格填充宽度网格setItems车辆网格addColumnVehicleValueProvider'ID'setCaption"ID"网格addColumnVehicleValueProvider'那么'setCaption"name"网格addColumnVehicleValueProvider''setCaption"使"网格addColumnVehicleValueProvider'型号名称'setCaption"模型"网格addColumnVehicleValueProvider'司机姓名'setCaption"name"格线 VehicleValueProvider 实施价值提供者propertyName VehicleValueProviderpropertyName这个propertyName propertyName覆写
        宾语应用宾语开关propertyName案件 'ID':
                    如果实例车辆返回车辆编号打破
                案件 '那么':
                    如果实例车辆返回车辆名称打破
                案件 '型号名称':
                    如果实例车辆返回车型名称打破
                案件 '':
                    如果实例车辆返回车辆名称打破
                案件 '司机姓名':
                    如果实例车辆返回车辆驾驶员姓名打破

            }
            空值
        }
    }

    静态的 私人的 纽扣buildSubmitButton最后 纽扣SubmitBtn 纽扣("添加到车库"SubmitBtn setStyleName"友好"SubmitBtn私人的updateVehicle最后 事件类型最后eventValue开关事件类型案件 'name':
                如果eventValue实例  ) {
                    这个车辆名称eventValue 
                }
                打破
            案件 '使':
                如果eventValue实例可选的 ) {
                    这个车辆制造事件值可选的得到打破
            案件 '模型':
                如果eventValue实例可选的 ) {
                    这个车辆型号eventValue可选的得到打破
            案件 '驱动器':
                如果eventValue实例可选的司机> ) {
                    这个车辆驾驶员eventValue可选的司机得到打破
            默认记录错误'用错误的eventType调用了updateVehicle'事件类型私人的提交vehicleService保存这个车辆一天navigationTogetUI getNavigator navigationTo查看名称结束对
    }
}
1 SpringView注释并设置名称,以便可以找到您的视图
2 该视图应扩展所需的布局样式
3 设置实际的视图名称
4 服务不会自动注入到Vaadin视图中,您需要使用自动接线批注,以使依赖项注入正常工作
5 告诉景色在里面在主界面之后执行在里面
6 急于装载车辆及其协会

急切加载在vehicleService列表全部为false需要进一步解释

365bet地区当Vaadin组件调用365bet地区服务时,一旦服务方法完成,休眠会话将关闭,这意味着查询未加载的任何关联都可能导致LazyInitializationException由于闭门会议

因此,至关重要的是,您的查询始终返回呈现视图所需的数据。这通常无论如何都会导致性能更好的查询,并且实际上将帮助您设计性能更好的应用程序

365bet地区365bet地区自动依赖项注入无法在Vaadin中检测服务,因此我们需要使用更传统的Spring注解Autowired才能使依赖项注入正常工作

在我们的案例中,我们的观点试图通过使用Rows来模仿许多现代Web设计的布局,我们在行中添加了标题数据收集和数据显示网格。

  • 创建布局

  • 创建UI组件

  • 将UI组件添加到布局

  • 添加布局以查看

将布局添加到视图时,您可以使用addComponent因为它知道它是自己添加的,而不像顶级UI根addComponent是必须的

为了保持文件干净,请继续将每个UI组件构建为自己的私有方法

一旦我们构建了UI组件,现在我们需要能够与它们进行交互。为此,我们使用groovy闭包将侦听器添加到组件中,以指定事件发生时将发生的情况。updateVehicle然后我们提交

src main groovy演示GarageView groovy
vehicleName addValueChangeListenerUpdateVehicleValueChangeListener'name'vehicleMake addSelectionListenerUpdateVehicleComboBoxSelectionLister'使'vehicleModel addSelectionListenerUpdateVehicleComboBoxSelectionLister'模型'vehicleDriver addSelectionListenerUpdateVehicleComboBoxSelectionLister'驱动器'SubmitBtn addClickListener事件这个提交

使用侦听器,我们构建了载具对象,然后在单击按钮时将其提交。Submit方法的最后一行重新加载视图以刷新新更新的数据。

src main groovy演示GarageView groovy
getUI getNavigator navigationTo查看名称

现在一切就绪,返回到运行App运行您的应用程序如果一切正常,您将看到以下内容

runningGarageApp

下一步

有很多机会可以扩展此应用程序的范围,以下是一些您可以自己进行改进的想法

  • 创建一个模式对话框对话框以添加新的司机, 使 & 楷模实例使用我需要子视窗给你一个良好的开端

  • 添加对现有更新的支持车辆实例模式对话框可能对此也很好,或者可能是可编辑的表格行

  • 目前使 & 模型域类彼此不相关在它们之间添加关联将使我们能够显示当前所选模型使在下拉列表中,您将要使用JavaScript Array过滤器方法

  • 当前,视图包含对服务的直接引用尽管对于演示或小型应用程序来说,这是完全可以的,但是当我们的代码库增长时,事情往往会变得一发不可收拾。诸如Model View Presenter MVP之类的模式可能有助于保持组织良好的代码库。模式和Vaadin我需要的书

您需要365bet地区帮助吗

OCI赞助了本指南的创建OCI提供了几种365bet地区服务:

免费咨询

OCI 365bet地区团队包括365bet地区联合创始人Jeff Scott Brown和Graeme Rocher检查我们的365bet地区课程并向发展和维护365bet地区的工程师学习

Grails OCI团队