转载

使用 Vaadin 在云中开发全堆栈 Java 应用程序

 

作为 Java 开发人员,您无需了解 HTML5、CSS 或 JavaScript 就可以开始创建交互式 Web 应用程序。借助 Vaadin 框架及其丰富的现成增件(add-on)和组件库,您可以通过使用熟悉的 IDE 和服务器端技术创建 100% 的全堆栈 Java 应用程序。我的 developerWorks 文章 “使用 Vaadin 实现全堆栈 Java Web 开发” 解释了 Vaadin 的幕后工作原理,帮助您开始使用 Vaadin 创建 Web 应用程序。

Vaadin 应用程序在 Bluemix 中表现良好,提供了 Vaadin Rich Web Starter 样板。部署在 Bluemix 上的 Vaadin 应用程序可以享受行业标准 Liberty Profile 应用程序服务器运行时支持,以及针对关系数据存储的 IBM DB2。Bluemix 上的所有 Vaadin 应用程序都可以充分利用各种丰富的、种类不断增长的服务器端服务。

在本教程中,我将引导您逐步为一个简单的 order desk(指令台)构建一个完整 Vaadin Web 应用程序。您将通过使用 Vaadin Contexts and Dependency Injection (CDI) 以及 Java Persistence API (JPA) 构造应用程序与组件,以便访问一个后端数据库。您会在熟悉的 Eclipse IDE 中进行编码,并将生成的应用程序部署到 Bluemix。

加入 为期 60 天的 IBM + Vaadin 挑战赛,参赛时间为 2015 年 10 月 1 日至 11 月 30 日。您可以炫耀从本教程及其配套教程中获得的技术, "使用 Vaadin 实现全堆栈 Java Web 开发",构建出色的应用程序并赢得奖品。

您将学习如何:

  • 通过在 Bluemix 上使用 Vaadin Rich Web Starter 样板开始您的 Vaadin 应用程序创建
  • 扩展一个 Vaadin CDI 应用程序,以便添加访问控制权
  • 使用来自您的 Web 应用程序中的 Vaadin 增件 目录中的两个第三方附加 UI 组件
  • 将一个登录页面添加到该应用程序,并对客户数据库进行身份验证。
  • 向应用程序添加一个订单搜索视图

观看:Vaadin 分步指南

观看:Vaadin 简介

阅读:教程:Vaadin 地址簿

Bluemix 上的所有 Vaadin 应用程序都可以充分利用各种丰富的、种类不断增长的服务器端服务。

前提条件

 

前提条件:

如果您想修改或研究该代码:

  • Java Development Kit (JDK) 1.7 或更高版本(此代码开发中使用了 1.7.0_60-b19)
  • Eclipse IDE for Java EE Developers (Luna 或更高版本)
  • Vaadin Plugin for Eclipse(来自 Eclipse Marketplace)
  • WebSphere Application Server Liberty Profile Web Profile v8.5.5.5 或更高版本(来自 Eclipse Marketplace,或者 IBM WebSphere Liberty Repository
  • Apache Derby 数据库(来自发行版的 derby.jar)10.11.1.1. 或更高版本

第 1 步. 探索应用程序的 UI

 

单击运行应用程序按钮(此步骤的前面)并尝试创建 order-desk 应用程序:

  1. 如果单击左边的任何菜单项(除了 About),您会看到登录页面。About 页面用于将数据加载到 Customer 数据库,这是实现登录要执行的必要操作。单击 Fill test data into DB 按钮。
  2. 在登录页面上,使用用户名 brian@robinson.com 和密码 abc123 进行登录:使用 Vaadin 在云中开发全堆栈 Java 应用程序

    点击查看大图

  3. 检查 Analyze 视图中的动画图表:使用 Vaadin 在云中开发全堆栈 Java 应用程序

    点击查看大图

  4. 浏览 Customer List 视图中的客户,查看 Map 视图中的客户位置: 使用 Vaadin 在云中开发全堆栈 Java 应用程序
  5. 使用 Search 视图搜索一个订单: 使用 Vaadin 在云中开发全堆栈 Java 应用程序

    点击查看大图

  6. 缩小浏览器页面宽度,查看应用程序如何作出相应的调整。
  7. 再次选择 Login-Logout 视图来退出登录,这意味着您不能再导航到其他任何视图。

第 2 步. 克隆和部署 Vaadin Bluemix 样板

 

本教程将开始介绍针对 Bluemix 的 Vaadin 样板中的代码并添加它。或者,您可以单击获取代码按钮(在本教程的 第 1 步. 探索应用程序的 UI 的前面),转到包含最终代码的 Bluemix DevOps Services 项目。然后,您可以将该项目中的最终代码与本教程中的样板版本进行比较。

  1. 登录您的 Bluemix 帐号(或 注册获得一个免费试用版)。
  2. 单击 Cloud Foundry Apps > CREATE APP
  3. 单击 Web,然后单击 Browse Boilerplates
  4. 单击 Vaadin Rich Web Starter使用 Vaadin 在云中开发全堆栈 Java 应用程序
  5. 为您的应用程序提供一个唯一名称并单击 CREATE。在创建应用程序时,会提供一个 IBM WebSphere Liberty Profile 服务器和 SQL Database 服务的一个免费测试实例(目前受 IBM DB2 支持)。
  6. 在您的计算机,克隆样板代码存储库:

    git clone https://hub.jazz.net/git/vaadin/vaadin-jpa-app

  7. 将目录更改为克隆的存储库:

    cd vaadin-jpa-app

  8. 构建应用程序,并创建 WAR:

    mvn install

  9. 从目录中删除 manifest.yml。
  10. 将 WAR 部署到 Bluemix:

    cf push appname -p target/vaadin-jpa-application.war

  11. 访问已部署好的样板 Vaadin 应用程序:http://appname.mybluemix.net/。该应用程序没有 Login 视图或 Search 视图,但有正常工作的 Customer List、Analyze 和 Map 视图。

第 3 步. 将您的项目加载到 Eclipse IDE 中

 

要修改或重新构建您的代码,可以将它加载到 Eclipse 中并重新构建 WAR。您必须使用 Maven 构建,而不是默认的 Eclipse 项目构建工作流。

  1. 将项目导入 Eclipse(File > Import > Existing Maven Project)。然后选择项目的根目录来完成导入。
  2. 查找 pom.xml 文件,右键单击它并选择 Run as > Maven install。查看流程控制台,可能需要花费一点时间,因为该流程要下载工件,为构建 WAR 而设置好一切。
  3. 将 Apache Derby 数据库 (derby.jar) 复制到您的 Liberty Profile 实例。将 derby.jar 从 Apache Derby 代码发行版拖动到 Enterprise Explorer 窗格中,并将它放在 WebSphere Application Server Liberty Profile/shared/resources/derby 文件夹中;该文件夹可能不存在,所以您可能需要创建它。
  4. 修改 Liberty Profile 实例的 server.xml 文件,使之包含 Java Naming and Directory Interface (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>
  5. 要成功运行您的 Vaadin CDI(上下文和依赖关系注入)应用程序,还必须在 server.xml 文件中包含以下行。为了获得最好的 Vaadin CDI 兼容性,应该使用这些代码行,而不是选择个别的 Liberty Profile 功能:

    <featureManager>
        <feature>localConnector-1.0</feature>
        <feature>webProfile-6.0</feature>
    </featureManager>
  6. 要在完成所有代码修改后重新构建 WAR,请选择该项目并右键单击 Run As > Maven Build。在第一次重新构建 WAR 时,会提示您选择一个目标。输入 package 作为 Maven 目标:使用 Vaadin 在云中开发全堆栈 Java 应用程序

    点击查看大图

  7. 要部署到本地服务器,请右键单击该项目中的 WAR,选择 Run As > Run on server,然后选择您的 Liberty Profile 实例。

第 4 步. 添加 Login 视图

 

如果您是 Java EE 6 上的 CDI 的新手,请查阅 JSR 299CDI 概述

样板应用程序使用了 Vaadin CDI 来处理自定义导航,并插入 UI 对象作为 CDI 托管 bean。Vaadin CDI 增件 位于 Vaadin Add-ons 目录中。

此外,在 Vaadin Add-ons 目录中,有一组 cdi-helpersUI 组件,Bluemix Vaadin 样板代码依赖于这些组件。研究这组辅助工具的操作可以帮助您了解如何在应用程序中使用 Vaadin CDI。

  1. 研究现有的代码,确保您了解 Vaadin CDI 在应用程序中的工作方式。整个应用程序 UI 是一个 ViewMenuUI UI 实例。您可以查看使得该实例成为 org.vaadin.presentation.AppUI 类中应用程序的主 UI 实例的代码。视图更改是通过成为 ViewMenu 一部分 Vaadin Navigator 实例来精心策划的。
  2. 要添加 Login 视图,请先添加一个名为 org.vaadin.presentation.views.LoginView 的新类,您可以从 源代码存储库 中复制它。Login 视图使用了一个来自 Vaadin Add-ons 目录的 Vaadin 组件加载项 — 由 Ingo Kegel 开发的 LoginForm UI 组件。

    要将此组件添加到您的项目中,必须在依赖关系部分将其 Maven 工件添加到项目的 pom.xml 文件:


    <dependency>
       <groupId>org.vaadin.addons</groupId>
       <artifactId>loginform</artifactId>
       <version>0.5.2</version>
    </dependency>
  3. LoginView 类中,该增件使得显示表单变得很容易:

    final DefaultVerticalLoginForm loginForm = new DefaultVerticalLoginForm();
        	loginForm.addLoginListener(new LoginListener() {
        	    @Override
        ...
    });
    ...
    add(loginForm);
  4. 要使用图标和文本标签来创建菜单项,并确保它是菜单上的最后一项,请使用 @ViewMenuItem() 注释:

    @ViewMenuItem(icon = FontAwesome.SIGN_IN, title = "Login-Logout", order = ViewMenuItem.END)

    告诉 Navigator 此视图是默认视图,请使用具有空白视图名称的 @CDIView()

    @CDIView("")

    如果您继续执行后续操作并修改样板,还需要更改 AboutView 的注释,将它从 @CDIView("") 更改为 @CDIView("about")

如果立刻构建和部署应用程序,它将在新的 Login 视图中运行,但什么都不会发生,因为您还没有访问控制权。

第 5 步. 扩展客户数据库来实现身份验证

 
  1. 要实现身份验证,需要将一个 password 字段、一个 role 字段和一个 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;
    	}
  2. org.vaadin.backend.CustomerService 类的 ensureTestData() 方法中,使用常数填充两个新字段:

    c.setRole("user");
    c.setPassword("abc123");
  3. CustomerListView 类中,在 adjustTableColumn() 方法中,添加您想要显示的字段:

    customerTable.setVisibleColumns("firstName", "lastName", "email",
                 "status", "role", "password");
    customerTable.setColumnHeaders("First name", "Last name", "Email",
                 "Status", "Role", "Password");
  4. 通过注入一个后端 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 访问控制

 
  1. 在允许访问视图之前,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>
  2. 要使用 RoleAllowed 注释来保护视图,请将代码行 @RolesAllowed({"user"}) 添加到每个视图(除了 LoginViewAboutView)。

    此更改可确保只有已登录的用户与用户角色可以访问该视图。(请回顾 第 5 步. 扩展客户数据库来实现身份验证,每一位客户都被设置为拥有用户角色。)

  3. 创建一个 org.vaadin.presentation.views.UserInfo 类来包含当前用户详细信息。此类被附加到 UIScope(专门的 Vaadin CDI 上下文,每个会话中都存在 UI 实例):

    @UIScoped
    public class UserInfo implements Serializable {
    private Customer user;
       private List<String> roles = new LinkedList<String>();
       ...

    查看 UserInfo 的源代码,获得全部的详细信息。

  4. 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);
        	        	...
                    }
  5. 默认情况下,会对照只包含一个具体的基于 Java 认证和授权服务 (JAAS) 实现的抽象 AccessControl 类来检查访问控制权。将这个类替换为您自己的已参照注入的 UIScoped UserInfo 实例检查过的 AccessControl 实现:

    @Alternative
    public class CustomAccessControl extends AccessControl {
    
        @Inject
        private UserInfo userInfo;
        
        @Override
        public boolean isUserSignedIn() {
            return userInfo.getUser() != null;
        }
      ...

    参见 org.vaadin.presentation.views.CustomAccessControl 的源代码,获得有关的详细信息。

  6. 要确保这个替代的 CustomAccessControl 实现被 Vaadin CDI 使用,必须向 beans.xml 文件添加一行代码:

    <alternatives>
        <class>org.vaadin.presentation.views.CustomAccessControl</class>
    </alternatives>
  7. 要实现注销,通过单击回到 Login-Logout page 页面的已登录用户可以通过重置视图的 onEnter() 方法中已注入的 UserInfo 实例来注销:

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
      user.setUser(null);
    }

如果立刻重新构建并运行应用程序,所有视图(除了 About)都会受到保护,您必须登录才能访问这些视图。在登录后,您可以通过再次选择 Login 视图来注销。

第 7 步. 添加 Search 视图

 

Search 视图是来自 Vaadin Add-ons 目录的开源第三方附加 UI 组件 — 是由 Teppo Kurki 开发的 FilteringTable UI 组件(源代码回购)。

  1. 添加 pom.xml 文件中的以下依赖关系来使用此组件:

    <dependency>
       <groupId>org.vaadin.addons</groupId>
       <artifactId>filteringtable</artifactId>
       <version>0.9.13.v7</version>
    </dependency>
  2. 添加来自最终的源代码的 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.SearchVieworg.tepi.filterable.demo.DemoFilterDecoratororg.tepi.filterable.demo.DemoFilterGenerator 中)只用于此演示视图的设置。您可以在空闲时间探索该代码。

  3. 构建 WAR 并运行应用程序。现在,您已经拥有完整的项目。查看最新更新的 源代码存储库 的自述文件。在 Maven 项目目录中,还可以通过使用 cf push 命令将完整的 WAR 部署到 Bluemix:

    cf push appname -p target/vaadin-jpa-application.war

结束语

 

Bluemix 上的 Vaadin 通过使用一个全堆栈 Java 方法,向 Java 开发人员提供了创建引人注目的交互式 Web 的能力。针对 Bluemix 的 Vaadin 样板提供了一个准备好部署的应用程序,可以很容易地扩展它来满足您的特定需求。

Vaadin Rich Web Starter 样板:演示了如何使用 Vaadin UI Framework 来构建丰富的 HTML5 应用程序,并在云中使用 Liberty for Java 运行时和 SQL Database 服务(受 DB2 支持)。

SQL Database 服务:(sqldb) 将向您的应用程序添加一个按需关系数据库。它由 DB2 驱动,提供了一个托管的数据库服务来处理要求苛刻的 Web 和事务性工作负载。

Bluemix Liberty for Java 运行时:可以帮助您轻松地开发、部署和扩展 Java Web 应用程序。IBM WebSphere Liberty Profile 是专为云设计的 IBM WebSphere Application Server 的高度可组合的、超快的、超轻型的配置文件。


相关主题:Java 开发Web 开发云计算


    
正文到此结束
Loading...