vaadin8开发手册
本文是使用Bluemix经典界面编写的。 随着技术的飞速发展,某些步骤和插图可能已更改。
作为Java开发人员,您无需学习HTML5,CSS或JavaScript即可开始创建交互式Web应用程序。 借助Vaadin框架及其庞大的易于部署的附件和组件库,您可以使用熟悉的IDE和服务器端技术来创建100%全栈Java应用程序。 我的developerWorks文章“ 使用Vaadin进行全栈Java Web开发 ”介绍了Vaadin的工作原理,并帮助您开始使用Vaadin创建Web应用程序。
Vaadin应用程序与Bluemix配合使用,后者提供了Vaadin Rich Web Starter样板。 在Bluemix上部署的Vaadin应用程序享受行业标准的Liberty Profile应用程序服务器运行时支持,以及用于关系数据存储的IBM DB2。 而且,Bluemix上的所有Vaadin应用程序都可以利用各种不断增长的服务器端服务。
在本教程中,我将逐步指导您为简单的订单创建完整的Vaadin Web应用程序。 您将通过使用Vaadin上下文和依赖注入(CDI)以及使用Java Persistence API(JPA)访问后端数据库,使用组件来构建应用程序。 您将在熟悉的Eclipse IDE中进行编码,并将所得的应用程序部署到Bluemix。
您将学习如何:
- 通过在Bluemix上使用Vaadin Rich Web Starter样板来启动Vaadin应用程序的创建
- 扩展Vaadin CDI应用程序以添加访问控制
- 使用Web应用程序中Vaadin 加载项目录中的两个第三方加载项UI组件
- 将登录页面添加到应用程序,并根据客户数据库进行身份验证。
- 将订单搜索视图添加到应用中
“ Bluemix上的所有Vaadin应用程序都可以利用各种不断增长的服务器端服务。 ”
你需要什么
需要:
- 一个Bluemix帐户
- Apache Maven 3.3或更高版本
- Git 2.5.2或更高版本
- Cloud Foundry命令行界面 6.12.3或更高版本
如果要修改或处理代码:
- Java Development Kit(JDK)1.7或更高版本(此代码的开发中使用1.7.0_60-b19)
- 适用于Java EE开发人员的Eclipse IDE (Luna或更高版本)
- Vaadin Eclipse插件(来自Eclipse Marketplace)
- WebSphere Application Server Liberty Profile Web Profile v8.5.5.5或更高版本(来自Eclipse市场或IBM WebSphere Liberty存储库 )
- Apache Derby数据库(来自发行版的derby.jar)10.11.1.1。 或更高
步骤1.探索应用程序的用户界面
单击“ 运行应用程序”按钮(在此步骤之前),然后尝试订购平台应用程序:
- 如果单击左侧的任何菜单项(关于除外),则将转到登录页面。 “关于”页面用于将数据加载到“
Customer
数据库中,这是登录工作所必需的。 单击将测试数据填充到数据库按钮。 - 在登录页面上,使用用户名
brian@robinson.com
和密码abc123
: - 在“ 分析”视图中查看动画图表:
- 在“ 客户列表”视图中浏览客户,并在“ 地图”视图中查看客户位置:
- 使用搜索视图搜索订单:
- 缩小浏览器页面宽度,以查看应用程序如何进行响应调整。
- 再次选择Login-Logout视图以注销,请注意您将无法再导航到任何其他视图。
步骤2.克隆并部署Vaadin Bluemix样板
本教程从Vaadin样板中的Bluemix代码开始,并将其添加到其中。 或者,您可以单击Get the code按钮(在本教程中的步骤1.探索应用程序的UI之前),转到包含最终代码的Bluemix DevOps Services项目。 然后,您可以按照本教程中的说明将项目中的最终代码与样板版本进行比较。
- 登录到您的Bluemix帐户 (或注册免费试用版 )。
- 单击Cloud Foundry应用>创建应用 。
- 单击“ Web” ,然后单击“ 浏览样板” 。
- 单击Vaadin Rich Web Starter :
- 为您的应用指定一个唯一的名称,然后点击创建 。 在创建应用程序时,将提供IBM WebSphere Liberty Profile服务器和SQL数据库服务的免费beta实例(当前由IBM DB2支持)。
- 在您的计算机上,克隆样板代码存储库:
git clone https://hub.jazz.net/git/vaadin/vaadin-jpa-app
- 将目录更改为克隆的存储库:
cd vaadin-jpa-app
- 生成应用程序,并创建WAR:
mvn install
- 从目录中删除manifest.yml。
- 将WAR部署到Bluemix:
cf push appname -p target/vaadin-jpa-application.war
- 通过http:// appname .mybluemix.net /访问已部署的样板Vaadin应用程序。 该应用程序没有“登录”视图或“搜索”视图,但是“客户列表”,“分析”和“地图”视图正在运行。
步骤3.将项目加载到Eclipse IDE中
要修改和重建代码,可以将其加载到Eclipse中并重建WAR。 您必须使用Maven构建而不是默认的Eclipse项目构建工作流。
- 将项目导入Eclipse(“ 文件”>“导入”>“现有Maven项目” )。 然后,选择项目的根目录以完成导入。
- 找到pom.xml文件,右键单击它,然后选择Run as> Maven install 。 观察控制台的进度,这可能需要一段时间,因为此过程将下载工件并设置了用于构建WAR的所有内容。
- 将Apache Derby数据库(derby.jar)复制到您的Liberty Profile实例。 将derby.jar从Apache Derby代码发行版拖放到Enterprise Explorer窗格中,并将其放置在WebSphere Application Server Liberty Profile / shared / resources / derby文件夹中; 该文件夹可能尚不存在,因此您可能需要创建它。
- 修改Liberty Profile实例的server.xml文件,以包括Java命名和目录接口(JNDI)数据源:
<jdbcDriver id="DerbyEmbedded" libraryRef="DerbyLib"/> <library filesetRef="DerbyFileset" id="DerbyLib"/> <fileset dir="${shared.resource.dir}/derby" id="DerbyFileset" includes="derby.jar"/> <!-- Configure an in-memory db for the vaadin app configuration --> <dataSource id="jdbc/vaadindb" jdbcDriverRef="DerbyEmbedded" jndiName= "jdbc/vaadindb" transactional="true"> <properties createDatabase="create" databaseName="memory:jpasampledatabase"/> </dataSource>
- 要成功运行Vaadin CDI(上下文和依赖项注入)应用程序,您还必须在server.xml文件中包括以下几行。 为了获得最佳的Vaadin CDI兼容性,请使用以下确切的代码行,而不是选择各个Liberty Profile功能:
<featureManager> <feature>localConnector-1.0</feature> <feature>webProfile-6.0</feature> </featureManager>
- 要在修改任何代码后重建WAR,请选择项目,然后右键单击Run As> Maven Build 。 首次重建WAR时,系统会提示您输入目标。 输入Maven目标的
package
: - 要部署到本地服务器,请右键单击项目中的WAR,选择“运行方式”>“在服务器上运行” ,然后选择Liberty Profile实例。
步骤4.添加登录视图
样板应用程序使用Vaadin CDI处理自定义导航,并将UI对象作为CDI托管bean注入。 Vaadin CDI附加组件位于Vaadin附加组件目录中。
另外,在Vaadin附加组件目录中,还有Bluemix Vaadin样板代码所依赖的一组cdi-helpers
UI组件( 源repo )。 研究这组帮助程序的操作将帮助您了解Vaadin CDI如何在应用程序中使用。
- 研究现有代码,以确保您了解Vaadin CDI在该应用程序中的工作方式。 整个应用程序UI是
ViewMenuUI
UI的实例。 您可以在org.vaadin.presentation.AppUI
类中看到使该实例成为应用程序主UI的代码。 视图更改由ViewMenu
一部分的VaadinNavigator
实例编排。 - 要添加登录视图,请首先添加一个名为
org.vaadin.presentation.views.LoginView
的新类,您可以从源存储库复制该类。 登录视图使用Vaadin附件目录中的Vaadin组件附件— Ingo Kegel的LoginForm
UI组件。要将这个组件添加到您的项目中,必须在依赖项部分中将其Maven工件添加到项目的pom.xml文件中:
<dependency> <groupId>org.vaadin.addons</groupId> <artifactId>loginform</artifactId> <version>0.5.2</version> </dependency>
- 在
LoginView
类中,该加载项使显示表单变得简单:final DefaultVerticalLoginForm loginForm = new DefaultVerticalLoginForm(); loginForm.addLoginListener(new LoginListener() { @Override ... }); ... add(loginForm);
- 要创建带有图标和文本标签的菜单项,并确保它是菜单上的最后一个菜单项,请使用
@ViewMenuItem()
批注:@ViewMenuItem(icon = FontAwesome.SIGN_IN, title = "Login-Logout", order = ViewMenuItem.END)
要告诉导航器此视图是默认视图,请使用
@CDIView()
和空白视图名称:@CDIView("")
如果要继续并修改样板,还需要将
AboutView
的注释从@CDIView("") to @CDIView("about")
。
如果您现在构建并部署该应用程序,它将在新的Login视图下运行,但是什么都不会发生,因为您尚未迷上访问控制。
步骤5.扩展客户数据库以进行身份验证
- 为了进行身份验证,您需要向客户数据库添加
password
字段,role
字段和名为query的findByEmail()
。 首先,在org.vaadin.backend.domain.Customer
类中修改域模型POJO:@NamedQueries({ ... @NamedQuery(name="Customer.findByEmail", query="SELECT c FROM Customer c WHERE LOWER(c.email) LIKE :filter") }) ... private String password; private String role; ... public String getPassword() { return password; } ... public void setRole(String role) { this.role = role; }
- 在
org.vaadin.backend.CustomerService
类的ensureTestData()
方法中,用常量填充两个新字段:c.setRole("user"); c.setPassword("abc123");
- 在
CustomerListView
类中,在adjustTableColumn()
方法中,添加要显示的字段:customerTable.setVisibleColumns("firstName", "lastName", "email", "status", "role", "password"); customerTable.setColumnHeaders("First name", "Last name", "Email", "Status", "Role", "Password");
- 通过注入后端
CustomerService
的实例使LoginView
起作用。 该服务用于从数据库中获取用户的电子邮件和密码信息。 注意,如果登录成功,则使用ViewMenuUI.getMenu()
导航器导航到AboutView
:public class LoginView extends MVerticalLayout implements View { @Inject private CustomerService service; ... Customer cust = service.findByEmail(event.getUserName()); if(cust != null) { ... System.err.println("PASSWORD verified"); ViewMenuUI.getMenu().navigateTo(AboutView.class); } else { System.err.println("PASSWORD invalid"); loginForm.clear(); } } else { System.err.println("no user found"); loginForm.clear(); }
如果您现在构建并运行该应用程序并尝试登录,它会将您重定向到AboutView
。 但是,由于尚未添加访问控制来保护视图,因此您仍然可以单击以查看客户列表或地图。
步骤6.添加CDI访问控制
- Vaadin CDI
CDIViewProvider
实现在允许访问视图之前会检查名为javax.annotation.security.RolesAllowed
的特殊注释。 访问冲突被定向到默认视图(在这种情况下为LoginView
)。 要将此批注添加到项目中,请将以下Maven依赖项添加到pom.xml文件中:<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.2-b01</version> </dependency>
- 要使用
RoleAllowed
批注保护视图,请将@RolesAllowed({"user"})
行添加到每个视图(LoginView
和AboutView
除外)。此更改可确保只有具有用户角色的登录
user
才能访问该视图。 (回想第5步。扩展customers数据库以进行身份验证 , 以确保每个客户都被设置为具有user
角色。) - 创建一个
org.vaadin.presentation.views.UserInfo
类以包含当前用户详细信息。 此类附加到UIScope
(会话中每个UI实例存在的专用Vaadin CDI上下文):@UIScoped public class UserInfo implements Serializable { private Customer user; private List<String> roles = new LinkedList<String>(); ...
有关完整的详细信息,请参见
UserInfo
的源代码。 - 将
UserInfo
注入LoginView
,以允许视图在成功登录时填充UserInfo
:public class LoginView extends MVerticalLayout implements View { ... @Inject private UserInfo user; ... public void onLogin(LoginEvent event) { ... Customer cust = service.findByEmail(event.getUserName()); if(cust != null) { if (cust.getPassword().equals(event.getPassword())) { user.setUser(cust); ... }
- 默认情况下,仅使用一个基于Java身份验证和授权服务(JAAS)的具体实现,对照抽象
AccessControl
类检查访问控制。 用您自己的AccessControl
实现替换该类,该实现将检查注入的UIScoped UserInfo
实例:@Alternative public class CustomAccessControl extends AccessControl { @Inject private UserInfo userInfo; @Override public boolean isUserSignedIn() { return userInfo.getUser() != null; } ...
有关详细信息,请参见
org.vaadin.presentation.views.CustomAccessControl
的源。 - 为确保Vaadin CDI使用此替代
CustomAccessControl
实现,必须在beans.xml文件中添加一行:<alternatives> <class>org.vaadin.presentation.views.CustomAccessControl</class> </alternatives>
- 为了实现注销,通过在视图的
onEnter()
方法中使用注入的UserInfo
实例的重置,可以注销单击“登录-注销”页面的所有已登录用户:@Override public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) { user.setUser(null); }
如果立即重建并运行该应用程序,则所有视图(“关于”除外)都将受到保护,并且必须先登录才能访问这些视图。 登录后,可以通过再次选择“登录”视图来注销。
步骤7.添加搜索视图
“搜索”视图是Vaadin附件目录中的开源第三方附件UI组件,即Teppo Kurki的FilteringTable
UI组件( 源repo )。
- 在pom.xml文件中添加以下依赖项以使用此组件:
<dependency> <groupId>org.vaadin.addons</groupId> <artifactId>filteringtable</artifactId> <version>0.9.13.v7</version> </dependency>
- 从最终源添加
org.vaadin.presentation.views.SearchView
类。 视图的UI部分是在init()
方法中构造的,非常简单。 此视图还受到@RolesAllowed({"user"})
:@CDIView("search") @RolesAllowed({"user"}) @ViewMenuItem(icon = FontAwesome.SUPPORT) public class SearchView extends MVerticalLayout implements View { private FilterTable filterTable; @PostConstruct void init() { filterTable = buildFilterTable(); add(filterTable); setExpandRatio(filterTable, 1); add(buildButtons()); setMargin(new MarginInfo(false, true, true, true)); setStyleName(ValoTheme.LAYOUT_CARD); } ...
SearchView
的其余代码org.vaadin.presentation.views.SearchView
,org.tepi.filterable.demo.DemoFilterDecorator
和org.tepi.filterable.demo.DemoFilterGenerator
-仅在此演示视图的设置中使用。 您可以在闲暇时浏览该代码。 - 生成WAR并运行该应用程序。 现在您已经完成了项目。 检查源存储库的自述文件以获取最新更新。 在Maven项目目录中,还可以使用
cf push
命令将完成的WAR重新部署到Bluemix:cf push appname -p target/vaadin-jpa-application.war
结论
Vaadin on Bluemix通过使用全栈Java方法使Java开发人员能够创建引人入胜的交互式Web体验。 用于Bluemix的Vaadin样板提供了一个易于部署的应用程序,可以轻松扩展该应用程序以满足您的特定需求。
vaadin8开发手册