vlambda博客
学习文章列表

读书笔记《digital-java-ee-7-web-application-development》数字Java EE 7

Chapter 1. Digital Java EE 7

 

“没有人比我更讨厌网站无法正常工作”

 
  --President Barack Obama, 21st October 2013 in a Rose Garden speech

数字改编是参与当代网页设计的软件开发人员的时代标志。数字化转型这个词是企业高管们迎合的另一个流行词。企业 Java 开发人员不必害怕这个新的数字世界,因为我们正在参与构建这个星球上最令人兴奋的软件。我们正在为用户、客户和人员构建软件。将单词 Digital 替换为 User Experience,您将立即获得大惊小怪的。

因此,让我们一劳永逸地删除营销条款。数字化转型采用非在线业务流程并产生等效的在线版本。当然,一只笨重的丑毛毛虫不会在一夜之间突然变成一只美丽的红海军上将蝴蝶,没有生活经验和基因。开发人员、设计人员和架构师需要具备相当的技能来适应、转换并将业务需求应用于技术。近来,软件行业已经认识到用户及其体验的有效性。本质上,我们已经成熟了。

这本书是关于能够成熟并且想要成熟的开发者的。这些是能够拥抱 Java 技术并同情相关 Web 技术的开发人员。

在本章中,我们将从 Web 开发人员、所谓前端工程师以及数字和创意行业的需求开始我们的开发人员之旅。我们将调查企业 Java 平台并提出一个问题,Java 适合哪些领域?我们将看看 JavaScript 的发展。我们将了解 Java EE 7 现代 Web 架构。最后,我们将以一个简单的 JavaServer Faces 示例结束。

Working in the digital domain


数字领域工作需要企业超越传统和制度化思维。将一些 HTML、一些新闻稿链接和一些白皮书拼凑在一起,将一些写得不好的 JavaScript 代码捆绑在一起,然后将其称为您的网站,这已不再可接受。曾几何时,这种策略是合适的。如今,私营和公共公司,甚至政府,通过专注于高可用性和内容(https://en.wikipedia.org/wiki/Long_tail)。如果您的网络技术难以使用,那么您将不会赚钱,也不会有公民使用您的在线服务。

Digital Java developer requirements


作为数字开发人员,您肯定需要功能强大的开发机器,能够同时运行多个应用程序。你需要坚强和自信,并坚持你的经验是最好的。你对自己的学习负责。数字开发人员不应该被适合销售和营销部门的笔记本电脑束缚。

您的主力 必须能够实际处理以下列表中每个工具的需求:

项目

解释

Java SE 8(或者,至少,Java SE 7)

Java SE 8 于 2014 年 3 月 18 日发布,它提供了 Lambda,其中函数是一等公民。 Java 7 是短期和谨慎的业务 IT 主管可接受的替代方案。

Java EE 7

GlassFish 4.1 应用服务器是 Java EE 7 的参考实现,但缺乏专业支持。或者,IT 主管可以考虑具有服务水平协议的红帽 JBoss WildFly 9。

集成开发环境

IDE,例如 IntelliJ IDEA 14、Eclipse Kepler 4.3 或 NetBeans 8

Adobe 创意套件

Adobe Photoshop CC(有时是 Adob​​e Illustrator)是创意数字媒体行业中事实上的图形作品。

黄瓜或硒

Cucumber 是一种行为驱动的开发,用于测试 Web 应用程序的功能。它是针对 Ruby 编程编写的,因此需要该环境和工具链。

一套现代网络浏览器

Mozilla Firefox、Google Chrome 和 Internet Explorer 10 以及支持 HTML5 和最新 W3C 标准的事实上的 Web 浏览器。需要最近与 Edge 一起启动的 Windows 10。

Web 浏览器的开发者插件

在您的工具集中拥有一个 JavaScript 调试器、HTML 和一个 CSS 元素检查器确实很有帮助。 Chrome 开发者工具等插件简化了数字工程。

文本编辑器

用于处理小规模工作的轻量级文本编辑器通常对于编辑 JavaScript、Puppet(或 Chef)脚本以及 HTML 和 CSS 文件非常有用。

仅通过查看这个软件表,就难怪普通的企业提供的公司笔记本电脑都没有足够的能力来处理这种开发。

Tip

数字工程师是聪明的专业工程师

我个人有一台 2012 MacBook Pro Retina 版本,配备 16 GB RAM、512 GB 静态硬盘驱动器作为我的主机。我的一些客户向我提供了配置错误的机器。一位特定的金融客户给了我一台只有 4 GB RAM 的戴尔 Latitude,运行 Windows 7 Professional。这台开发机器性能太差了,我不得不抱怨很多次。告知您企业中的决策者,数字工作者需要足够的开发机器,以满足工程和设计出色用户体验的目的。

让我们从创意和设计转向 Java 平台。

Java in the picture


Java 平台 在今天被广泛使用。它是第一个以 JVM 和字节码为特色的商业语言,具有垃圾收集、沙盒安全性和 网络功能,被企业采用。 Java 的最大优势在于企业信任该平台来支持服务器端计算中的企业应用程序。自 1995 年以来,这种深度力量已经发展到该平台被视为非常成熟和主流的水平。成为主流的缺点是创新需要一段时间才能发生;作为平台的管理者,早期的 Sun Microsystems 和现在的 Oracle Corporation,始终通过 Java Community Process 保证向后兼容性和标准的维护。

JVM 是该平台的皇冠上的明珠。 Java 是在 JVM 上运行的母编程语言。 Scala、Groovy 和 Clojure 等其他语言也运行 JVM。这些替代 JVM 语言很受欢迎,因为它们向主流开发人员介绍了许多函数式编程思想。函数式编程原语(例如闭包和推导式)以及诸如 Scala 之类的语言展示了纯面向对象的模型和混入。这些语言得益于名为 REPL 的简单交互 工具。

Tip

事实上,Java SE 9 很可能会有 Read-Evaluate-Print-Loop (REPL< /strong>)。在 http://openjdk 上关注官方 OpenJDK 项目 Kulla 的进展。 java.net/projects/kulla/

Java SE 8 于 2014 年发布,具有函数式接口,也称为 Lambda,它将闭包和函数块的 优势带入平台上的主要 JVM 语言.

无论您选择哪种编程语言来开发您的下一个企业应用程序,Java 或 Scala 或其他,我认为您可以押注 JVM 存在很长时间,至少在未来十年左右。 PermGen 问题最终在 Java SE 8 中结束,因为那里没有永久代。在 Java SE 8 之前,PermGen 是许多内存泄漏(缓慢而稳定的内存消耗)的根源。这也是 JVM 将类加载到一块内存中的专用空间,例如 Java 运行时(例如 java.lang.Stringjava.lang.System,或 java.util.collection.ConcurrentHashMap)。然而,类的大小很少被卸载或压缩,尤其是在 JVM 很长的执行过程中。如果您在数天甚至数周内一次 24/7 全天候运行网站,并且有一定程度的用户交互,那么您的应用程序(及其应用程序服务器)很有可能内存不足(java.lang.OutOfMemoryError: PermGen space)。永久代是在 JDK 8 之前的版本中为 Java 类的内部表示保留的存储区域。对于长时间运行的应用程序服务器和 JVM 进程,即使在 WAR/EAR 之后,对元数据和类的引用也可能保留在永久代内存中应用程序被取消部署和卸载。在 Java SE 8 中,为 Java 类保留的内存分配是自适应的。 JVM 现在可以优雅地管理自己的内存分配,与以前的版本相比,效率至少提高了 10%。

在 Java SE 8 中,我们 有一个称为 G1 的 Garbage First 垃圾收集器,它是一个并行收集器。 Java SE 8 还包括新的字节码,以提高 JRuby 和 Clojure 等动态语言的效率。来自 JDK 7 的 InvokeDynamic 字节码和 Method Handle API 专门为 Nashorn(JavaScript 的一种实现(ECMAScript Edition 6))进行了检测。

Tip

自 2015 年 4 月起,Oracle 停止向其公共下载站点发布 Java SE 7 更新。请将此信息传递给您的 CTO!

毫无疑问,Java 平台将继续作为后端技术为数字工程师服务。企业甚至可能会想到利用 Java SE 8 中的客户端技术,该技术现在随平台一起提供。 JavaFX 是一个有趣的解决方案,但超出了本书的范围。

我们现在应该介绍一些代码。以下是 Java SE 8 的 Lambda 函数:

public interface PaymentIssuer {
  public void allocate( int id );
}

@ApplicationScoped
public class CreditCardTicketTracker() {
  // Rely on CDI product factory to inject the correct type
  @Inject PaymentIssuer issuer;
 
  public void processTickets( List<Ticket> ticketBatch ) {
  final LocalDate dt = LocalDate.now().plusDays(2)
    ticketBatch.stream()
      .filter(
        t -> t.isAvailable()  &&
        t -> t.paymentType == PaymentType.CreditCard &&
        dt.isBefore(DateUtils.asLocalDate(
      t.getConcertDate())))
      .map(t -> t.getAllocation().allocateToTicket(t))
      .forEach(allocation -> issuer.allocate(allocation));
  }
}

如果这段代码对您来说很陌生,那么您可能还不熟悉 Lambda 表达式。我们有一个 Context and Dependency Injection (CDI) bean,这是应用程序作用域,称为CreditCardTicketTracker。它有一个名为 processTickets() 的方法,该方法接受 Ticket 对象的列表集合。 Ticket 的确切类型并不重要。然而,重要的是 CDI 注入 Plain Old Java ObjectPaymentIssuer 类型>(POJO)。 方法 processTickets() 调用 Java SE 8 集合的流 API。本质上,调用 parallelStream() 方法会导致对 Java 集合中的每个元素进行处理,同时多个线程在并发操作中工作。 Lambda 表达式位于 filter()map()forEach( ) 更新的 Collection API 的方法。

此外,代码读起来与书面英语足够接近。现在让我解释一下方法processTickets()。一个外部组件正在向我们的 组件 CreditCardTicketTracker 发送批量音乐会门票以进行处理。对于批次中的每张门票,我们仅过滤那些标记为可用的门票,这些门票已经使用信用卡支付,并且音乐会日期在当前日期后两天或更长时间。顺便说一句,我们利用了 Java SE 8 中新增的 java.time.LocalDate

因此,非常简单地说,Lambda 表达式是一种匿名方法,语法遵循以下格式:

( [[Type1] param1 [,  [Type2] param2 ....]] ) -> { 
  /*
   * Do something here and return a result type
   * including void
   */
}

lambda 表达式 可以是无参数的;因此,Java 编译器可以推断出一个表达式可以替代 java.lang.Runnable 类型。如果有参数,编译器可以在给定足够信息的情况下推断参数的类型。因此,Type1 和 Type2 声明是可选的。 Lambda 必须返回一个类型的单个实例,否则它可能是 void,这意味着花括号可能会被省略。

Lambda 表达式简洁、省时,并且允许将函数传递给库。有关更多信息,请参阅 Oracle 网站 (http://docs.oracle.com/javase/tutorial/java/index.html)。正如我们在前面的示例中看到的,您的应用程序可以使用集合中的并行流工具来实现并发。

Lambda 表达式的一种直接用途是替换调用托管线程服务的内部类,即 Java EE 7 中的 javax.enterprise.concurrent.ManagedExecutorService。我们知道 Java 有多个-线程支持、网络和安全性。让我们把注意力转向客户端。

The impressive growth of JavaScript


在过去的 十年中,数字工程师对 JavaScript 作为一种编程语言采取了健康的尊重。尽管存在许多缺点,但开发人员已经学会编写真正利用这种编程语言功能的模块化应用程序,这种编程语言在网络浏览器和服务器中普遍执行。最终改变游戏规则的框架叫做 jQuery。然后它由 John Resig 编写,以简化 JavaScript 中 HTML 的客户端脚本。它于 2006 年发布,是当今 JavaScript 库 中最流行的框架。

jQuery 中最大的创新是名为 Sizzle 的选择器引擎,它允许 JavaScript 编程通过声明过滤掉 DOM 元素,允许遍历,并通过一种集合理解执行算法。它为 JavaScript 开发引入了新的方向。

驱动 JavaScript 的不仅仅是 jQuery。事实上,进步可以追溯到 AJAX 技术的重新发现和 几个竞争框架的出现 诸如Script.aculo.us原型

以下是使用 jQuery 的 JavaScript 代码的 示例:

var xenonique = xenonique || {}

xenonique.Main = function($) {
    // Specifies the page marker ID
    var siteNavigationMarker = '#navigationMarker';

    var init = function() {
      $(document).ready( function() {
        $('#scrollToTheTopArrow').click( function() {
        $('html, body').animate({
                scrollTop: 0
            }, 750);          
        })      
      })
    }

    var oPublic = {
       init: init,
        siteNavigationMarker: siteNavigationMarker,
    };

    return oPublic;
}(jQuery);

如果您难以理解前面的代码,请不要担心,当然也不要逃避这段 JavaScript。该代码展示了以良好、可靠和可维护的方式开发 JavaScript 而不使用全局变量的现代习惯用法。它完美地说明了将 JavaScript 变量和函数方法保存在封闭范围内的模块技术。作用域是 JavaScript 编程中要理解的最重要的项目。

前面的 JavaScript 代码创建了一个名为 xenonique 的命名空间,它 存在于自己的范围内。我们利用 Module Pattern 创建一个名为 Main 的模块,它依赖于 jQuery。定义了一个名为 init() 的方法,它使用匿名函数执行 jQuery 选择器。每当用户单击 ID 为 #scrollToTheArrow 的 HTML 元素时,网页会在 750 毫秒内自动滚动到顶部。

The JavaScript module pattern

正如 Douglas Crockford 在他的开创性著作 JavaScript: The Good Parts 中阐述的,这段代码中的关键技术是创建一个模块,其行为类似于一个单例对象。解释器立即调用该模块,因为声明的末尾 的参数参数语句依赖于 jQuery 实例。

让我们简化模块以获得效果:

var xenonique = xenonique || {}

xenonique.Main = function($) {
    /* ...a */
    return oPublic;
}(jQuery);

上述代码中的模块 xenonique.Main 实际上是一个 JavaScript 闭包,它有自己的作用域。因此,模块模式模拟私有和公共成员和功能。闭包的返回值是一个定义可公开访问的属性和方法的对象。在模块中,init() 方法和 siteNavigationMarker 属性可供其他 JavaScript 变量公开访问。闭包保存在带有 JavaScript 执行上下文的返回对象中,因此,所有私有和公共方法都将存在于应用程序的整个生命周期中。

JavaScript advanced libraries

对于一些 工程师来说,编写自定义 JavaScript,甚至围绕一个 jQuery 选择器也是如此详细而低级。 AngularJS 是 JavaScript 框架的一个例子,它进一步推动了客户端编程的发展。 AngularJS 尤其具有将 DOM 元素声明式地相互绑定或与 JavaScript 模块代码进行双向数据绑定的特点。 AngularJS 的创建者打算带来Model-View-ControllerMVC) 设计模式和对 Web 应用程序开发的关注点分离,以及激发行为驱动设计 通过内置的测试框架。

AngularJS (http://angularjs.org/) 是 JavaScript 中的新现代运动的亮点之一。虽然每周都会发明一个 JavaScript 库,但专业开发生活中的佼佼者似乎还包括 GruntJS、Node.js、RequireJS 和 UnderscoreJS。

GruntJS (http://gruntjs.com/) 是 特别有趣,因为它的工作方式类似于 在 C 或 C++ 中制作,在 Java 空间中使用 Maven 或 Gradle。 Grunt 是一个 JavaScript 任务管理系统,它可以构建应用程序、执行单元测试、将 Sass 和 LESS 文件编译为 CSS,以及使用资源执行其他任务。它还可以调用实用程序,使用称为压缩的过程压缩 JavaScript,并将它们优化为丑陋(难以逆向工程)的文件,以提高速度和一定程度的安全性。

Note

Sass (http://sass-lang.com/) 和 LESS (http://lesscss.org/) 是 CSS 设计人员和开发人员使用的预处理器。这些 工具 将可重复使用的通用样式配置转换为特定的设备和站点样式表。

对于一个新的数字工程师,我想你可能会觉得这个讨论势不可挡。所以我将其总结在下表中:

JavaScript 项目

描述

jQuery

最重要的开源 JavaScript 库,用于操作 DOM 和按 ID 和名称选择元素。它有一个非常流行的插件架构,在 上提供了许多产品。

http://jquery.org/

jQuery 用户界面

这是一个 流行的插件,它扩展了标准的jQuery,并添加了额外的动画、可定制的主题和UI 包括日期日历选择器的组件。

http://jqueryui.org/

要求JS

JavaScript 文件和模块加载器的 依赖管理框架。该框架能够为大型应用程序优化模块包,尤其是通过异步模块定义API。

http://requirejs.org/

纳肖恩

一个由 Oracle 构建的 JavaScript 运行时引擎,作为标准与 Java SE 8 一起提供。Nashorn 在 JVM 上运行,它是开放的 源码,是 OpenJDK 项目的一部分。

http://openjdk.java.net/projects/nashorn/

Dojo Toolkit 和微内核架构

一个重构的 JavaScript 模块化框架和工具包,其中包含小部件 组件。它利用 AMD 实现快速 下载速度和模块效率,仅加载客户端应用程序所需的内容。 Dojo Toolkit 具有有用的图表和可视化组件。

http://dojotoolkit.org/

灰烬 JS

Ember 是 一个用于构建客户端Web 应用程序的框架。它使用 JavaScript 调用模板来生成页面内容。 Ember 面向希望与原生应用程序竞争的移动开发人员。该框架使用 Handlebars 模板库。

http://emberjs.com/

车把 JS

Handlebar 是一个用于 客户端 Web 应用程序的 JavaScript 模板库。在第一次检查时,模板类似于添加了表达式标记的 HTML。熟悉 AngularJS 的人会发现这些表达式在语法上非常相似。

http://www.handlebarsjs.com/

下划线 JS

这是一个 JavaScript 开发者库,将 函数式编程思想和构造引入语言通过 API。它有 80 多个库助手,包括 select、map、flatMap、filter、reduce、forEach 和 invoke 等方法。

http://underscorejs.org/

骨干JS

向客户端 应用程序添加建模方面的 JavaScript 框架。它为模型提供了与 DOM 和自定义应用程序事件的键值绑定。模型和 集合可以保存到服务器。 Backbone 还提供了带有声明性数据绑定的视图。在很多方面,这个框架被视为AngularJS的一个可行的竞争对手。

http://backbonejs.org/

角 JS

AngularJS 是一个 JavaScript 框架,它在 DOM 元素和自定义 JavaScript 模块代码之间提供双向数据绑定。它具有模型-视图-控制器架构,还通过称为指令的功能提供对自定义 HTML 组件的支持。目前在谷歌工作的开发人员也大力支持 Angular JS,因此它是一个著名的 JavaScript 框架。它的优势在于单页Web 应用程序和声明式编程。

http://angularjs.org/

如您所见,如果您碰巧与精通上述许多方面的前端(界面开发人员)工程师一起工作,将面临很多挑战 技术。企业 Java 或服务器端工程师 必须了解其他人的技能组合。 (请参阅附录 C敏捷性能 - 在数字团队中工作< /em>)。

Information architecture and user experience


如今,数字工作者面临着多种输入和客户设计要求。其中一个 是所谓的信息架构IA)。这本质上是关于网站的静态结构,并描述了流程 以获得最佳的客户-用户体验。信息架构对客户可以在网页、应用程序和环境中看到的共享视觉和上下文数据进行建模。

大多数 Java 工程师可能已经看到在业务团队讨论期间在设计人员和业务分析师之间传递 IA 图。简单地掩盖或忽略这些讨论是错误的,这就是为什么数字开发人员应该了解如何、为什么以及在哪里应用 IA。它看起来有点像站点地图的可视化。以下是电子商务应用程序的信息架构图示例:

读书笔记《digital-java-ee-7-web-application-development》数字Java EE 7

时装店网站的基本信息架构

前面的 图描述了潜在时尚商店 Web 应用程序的 IA。这本书可能被认为过于简单化。然而,这个图表是一个正在进行的宣传工作,一个销售会议,目的是赢得开发和构建 Web 应用程序的合同。架构基于对客户至关重要的三个组件:初始欢迎页面、对目录和产品的访问以及有关公司的内容。对于这个特定的客户,该图表反映了他们对特色时尚商品、品牌和促销活动的关注。 IA 将通过与客户的进一步互动随着时间的推移而发展。如果我们赢得开发时尚商店应用程序的竞标,则可能需要更深入调查的网站的可搜索性。

信息架构帮助设计人员和开发人员以及业务利益相关者通过一种整合了领域知识和目的的共享语言来理解网站的结构。网站所有者和企业可以将 IA 视为内容的细分。他们可以理解网站是如何构建的。

信息架构也可以是关于内容的动觉反应(某人内心的感受) )。将来,这对于可穿戴计算机将很重要,因为用户可能不会在屏幕上查看感觉和通知。交互可能是通过声音,甚至是通过气味或味道。这些建模技术和以具有情感影响的方式写作的能力被包含在一个新的和最近的职位中:内容策略师。

编写和构建专业网站或企业应用程序已经从婴儿期开始。开发人员现在必须平易近人、适应能力强且老练。平易近人意味着与他人和团队和谐相处的能力。适应能力意味着在不断的挑战和变化面前无所畏惧;成熟意味着能够应对压力并优雅地处理它。

让我们继续了解企业 Java 平台的技术方面。

Java EE 7 architecture


Java EE 是一个开放标准、一个企业平台,以及在 服务器上执行的应用程序的规范。对于数字工作者,Java EE 提供了许多用于构建 Web 应用程序的服务,包括 Servlet、JavaServer Faces、Facelets、上下文和依赖注入、Java 消息服务、WebSocket 以及用于 RESTful 服务的关键 Java。

Java EE 7 于 2013 年 6 月宣布并发布,其主题是更好的 HTML5 支持和提高生产力。目前,看起来未来的 Java EE 8 规范可能会通过声明性注释(JSR 220 的扩展)添加对服务和应用程序方面的管理配置的支持。

Standard platform components and API

Java EE 架构是一个容器和基于层的 架构。设计的关键是应用服务器和越来越基于云的解决方案,尽管这尚未在规范中标准化。

在非基于云的 Java EE 中,我们可以将 Java EE 视为四个独立的容器:第一个是 EJB 容器,用于 Enterprise Java Bean 的生命周期管理,第二个容器是 Web 容器,用于企业 Java Bean 的生命周期管理。 Java Servlet 和托管 Bean。第三个容器称为应用程序客户端容器,它管理客户端组件的生命周期。最后,第四个容器是为 Java Applet 及其生命周期保留的。

大多数 时间,数字工程师都关心 EJB、Web 和托管 CDI bean 容器。

Note

如果您对架构的完整描述感兴趣,请参阅我的第一本书,Java EE 7 开发人员手册,作者为 Packt 发布。您可以将其视为此书的姊妹书。

根据 Java EE 7 规范,有两种官方实现配置文件:完整配置文件和 Web 配置文件。 Glassfish 或 JBoss WildFly 应用服务器等完全符合标准的 Java EE 产品实现了完整的配置文件,这意味着它具有所有容器:EJB、CDI 和 Web。像 Apache Tomcat 这样的基于 Java EE 7 Web 配置文件构建的服务器仅实现 Web 容器。像 Tom EE 这样扩展 Apache Tomcat 的服务器实现了 Web 容器,并且可以添加额外的工具,如 CDI、EJB,甚至 JMS 和 JAX-RS。

下图说明了作为企业解决方案的完整配置文件 Java EE 7 架构。 Java EE 平台是硬件、磁盘存储、网络和机器代码的抽象。 Java EE 依赖于 Java 虚拟机的存在进行操作。有些版本的 JVM 已移植到 Intel、ARM、AMD、Sparc、FreeScale 等硬件芯片以及 Windows、Mac OS、Linux、Solaris 甚至 Raspberry Pi 等操作系统。

因此,Java 和其他替代语言可以在这种芯片架构上无缝执行,这适用于企业应用程序。 Java EE 为标准核心 Java SE 提供了额外的标准 API。让我们简要介绍一下 Java EE 的一些特性。

Java EE 7 New Input OutputNIO) Java SE 版本中的功能,允许 Java Servlets 3.1 处理异步通信。

JavaServer Faces 2.2 现在通过更紧密的 CDI 集成、改进的生命周期事件和 AJAX 请求的新队列控制得到了增强。对于数字工程师来说,有明智的 HTML5 支持、资源库合同、面孔流和无状态视图。

读书笔记《digital-java-ee-7-web-application-development》数字Java EE 7

Java EE 7 全平台和 JSR 规范的图示

Expression Language 3.0 并不是真正的新规范,但它是从 Servlet、JavaServer Pages 和 ="indexterm"> JavaServer Faces。开发人员可以访问表达式评估器并调用自定义表达式的处理,例如他们自己的自定义标记库或服务器端业务逻辑。

也许,Java EE 7 中最重要的变化是 CDI 的加强,以提高类型安全性和更容易开发 CDI 扩展。 CDI、拦截器和通用注释改进了类型安全的依赖注入和对 CDI 容器内生命周期事件的观察。这三个规范共同确保可以编写解决横切关注点并且可以应用于任何组件的扩展。开发人员现在可以编写可移植的 CDI 扩展,以标准方式扩展平台。

RESTful 服务 (JAX-RS) 具有三个重要的增强功能:添加客户端 API 以调用 REST 端点、对客户端和服务器端点的异步 I/O 支持以及超媒体链接。

Bean 验证是针对域和值对象的约束验证解决方案。它现在支持方法级验证,并且与 Java EE 平台的其余部分有更好的集成。

WebSocket API 1.0 是添加到 Java EE 7 的新规范。它允许 Java 应用程序与 HTML5 WebSocket 客户端进行通信。

Java EE 7 延续了该平台早期版本的主题:改进了开发的简易性并允许开发人员编写 POJO。

Xentracker JavaServer Faces


现在让我们进入 开发模式。我们将看一下我为之前的书创建的 JSF 示例。该项目名为 XenTracker。代码可在 https://github.com/peterpilgrim/javaee7-developer -手册。以下是 JSF 视图(xentracker-basic/src/main/webapp/views/index.xhtml):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://java.sun.com/jsf/core">

  <ui:composition template="/views/template.xhtml">
    <f:metadata>
      <f:viewParam name="id" value="#{taskListViewController.id}" />
      <f:event type="preRenderView" listener="#{taskListViewController.findProjectById}"/>
    </f:metadata>

    <ui:define name="content">

      <div class="entry-form-area">

        <h1>Task List for Project</h1>

        <p>
          <h:outputText value="Task list for this project:"/>
        </p>

        <h:link styleClass="btn btn-primary" outcome= "createTask.xhtml?id=#{taskListViewController.id}">
        <f:param name="id" value="#{taskListViewController.id}" />
        Create New Task
        </h:link>

        <table class="table table-striped table-bordered" >
          <tr>
            <td>Title:</td>
            <td><strong>
             &#160;#{taskListViewController.project.name}
            </strong></td>
          </tr>
          <tr>
            <td>Headline:</td>
            <td>&#160;
            #{taskListViewController.project.headline}</td>
          </tr>
          <tr>
            <td>Description:</td>
            <td>&#160;
            #{taskListViewController.project.description}</td>
          </tr>
        </table>
        <!-- form table grid see below -->
      </div>
    </ui:define>
  </ui:composition>
</html>

乍一看,这看起来像是标准的 HTML5;特定的 JSF 标记和表达式语言语法并不那么明显。项目中文件的名称称为 projectTaskList.xhtml,它为该文件所代表的视图类型提供了重要线索。这个视图实际上是一个 JSF Facelet 模板。文件类型指的是较旧的 XHTML 标准,由 万维网联盟 (W3C ) HTML 4.01 标准创建之后。 XHTML 与 HTML4 相同,但受 XML 模式的限制,因此是真正的 XML 文档。

为了 呈现来自 JSF 的任何输出,规范规定提供 页面描述语言PDL)。可能有不止一种类型的 PDL。标准 PDL 是一种称为 Facelet 视图模板的视图。 Facelet 框架是 JCP 外部的一个单独的开源 API,但自 JSF 2.0 起,它已被纳入其中。 Facelet 模板被设计为轻量级的,并且可以与 JSF 框架一起工作。 Facelets 具有 JSF 生命周期的隐含知识,可以通过表达式语言访问 UI 组件,并且它们为标准 HTML 元素提供装饰器。 Facelets 模板解决方案在 servlet 引擎中执行得非常好。它最终可能会出现在自己的 Java EE 8 规范中。

前面示例中的模板由特定的 Facelet 标记说明,即 <ui:define><ui:composition> 。简而言之,<ui:composition> 标签指的是定义页面布局的模板视图。可以将其视为主视图。 <ui:define> 标签定义了实际的内容,将被插入到模板中以形成最终的页面输出。我们将在本书后面的章节中全面介绍 JSF 和 Facelets。

通过检查视图定义顶部的开放 XML 定义,我们可以看到一些命名空间声明。如您所见,xmlns:ui 命名空间指的是 Facelet 扩展。 xmlns:f 命名空间是指核心 JSF 标记,而 xmlns:h 命名空间是指呈现 HTML 元素的 JSF 组件.警告您不要期待完整的一对一匹配,稍后您将了解。例如,<h:outputText> 标签只是打印出内容;您几乎可以将其视为 PHP 中的 echo 函数。

你们当中真正细心的人会发现,使用 JSF 构建现代网站绝对是可能的。标记中有一个 <div> 元素,是的,您可能猜对了,Bootstrap CSS 肯定被使用了。重要的是要强调 JSF 是一种服务器端模板解决方案和一种视图技术。

再次查看以下部分:

<h:link styleClass="btn btn-primary" outcome="createTask.xhtml?id=#{taskListViewController.id}">

这大约相当于这个直接的 HTML5:

<a style="btn btn-primary" href="JSF_munged_createTask.xhtml?id=jsf_fizz_12345">

在 JSF 中,句法分隔符表示 表达式:#{...}。表达式语言在生命周期的呈现阶段在 JSF 运行时中进行解析。我们将在接下来的章节中讨论生命周期。

之前的 视图不完整,因为我们缺少表格视图组件。尽管 HTML 表格由于网页内容的布局而受到反对,但表格对于其最初的用途,即显示表格数据仍然非常重要。

以下是应插入正确位置的缺失表视图:

<h:form>
  <h:dataTable id="projects" value="#{taskListViewController.project.tasks}" styleClass="table table-bordered" var="task">
    <h:column>
      <f:facet name="header">
        <h:outputText value="Task Name" />
        </f:facet>
        <h:outputText value="#{task.name}"/>
    </h:column>
    <h:column>
      <f:facet name="header">
        <h:outputText value="Target Date" />
      </f:facet>
        <h:outputText value="#{task.targetDate}">
          <f:convertDateTime pattern="dd-MMM-yyyy" />
        </h:outputText>
    </h:column>
    <h:column>
      <f:facet name="header">
        <h:outputText value="Completed" />
      </f:facet>
      <h:outputText value="#{task.completed}"/>
    </h:column>
    <h:column>
      <f:facet name="header">
        <h:outputText value="Action" />
      </f:facet>
      <h:link styleClass="btn" outcome="editTask.xhtml?taskId=#{task.id}">
        <f:param name="taskId" value="#{task.id}" />
        <i class="icon-edit"></i>
      </h:link>
      <h:link styleClass="btn" outcome="removeTask.xhtml?taskId=#{task.id}">
        <f:param name="taskId" value="#{task.id}" />
          <i class="icon-trash"></i>
      </h:link>

    </h:column>
  </h:dataTable>
  <hr/>
  <h:commandLink styleClass="btn btn-primary btn-info" immediate="true" action="#{taskListViewController.returnToProjects}">
    Return to Projects</h:commandLink>
</h:form>

前面的代码举例说明了 JSF 内容风格。 <h:form> 标签对应于 HTML 表单元素。 <h:dataTable> 标记表示从托管 JSF bean 呈现数据的表格组件网格。 value 属性表示从名为 taskListViewController 的服务器组件中检索的数据。此控制器使用表达式语言访问任务对象的列表集合,并将其转换为 taskListViewController.getProjects().getTasks() 的 Java 反射调用。再次值得注意的是 styleClass="table table-bordered" 属性中的 Bootstrap CSS。

<h:dataTable> JSF 组件本质上迭代 Java 集合、数组、迭代器或枚举器,设置由属性 var,并处理其正文中的内容。它构建一个 HTML 表。 <h:column> 标签声明行的每一列的内容,<f:facet> 标签声明专门进入表格标题行的内容。

<h:outputText> 标签也足够灵活,可以接受另一个常用标签 <f:convertDateTime>,它的格式为特定数据值转换为日期时间格式。

最后,我们有 h:commandLink 标记,该标记呈现 HTML 锚标记,其行为类似于表单提交按钮。 h:commandLink 标记可选地与支持 bean 关联,在我们的例子中是 taskListViewController。 JSF HTML 标记的某些组件,如 h:dataTableh:commandLink 包含在 h:form 标记以便正确处理。

Tip

引导 CSS (http://getbootstrap. com) 是一个非常流行的CSS、组件和前端框架,用于开发响应式网站。它特别适用于 默认项目的移动设备,因为它建立在灵活且流动的网格系统之上。 CSS 和 JavaScript 很容易添加到 Web 应用程序中; Bootstrap 确实是许多项目的启动器。

Application servers


在编写 时,有几个流行的应用服务器被认证为符合 Java EE 7:GlassFish、WildFly、Payara、Cosminexus 和 TMax Jeus 8 . 整个伞形规范的参考实现是 GlassFish 4.1 (https://glassfish.java.net/)。 2013年,我奉献了整本姊妹书和源代码示例, Java EE 7 Developer Handbook,对于 GlassFish,因为它是唯一可用的服务器。 GlassFish 建立在开源基础上,有一个公共问题跟踪器,许多关于各种 Java EE 主题的论坛,而且由于 Oracle 支持源代码的主机和存储库,它开箱即用。

为了被认证为 Java EE 7 应用服务器,供应商或开源提供者必须通过 测试兼容性工具包,该工具包保证 合规认证列表(http://www.oracle.com/technetwork/java/javaee/overview/compatibility-jsp-136984.html)。仅针对 Java EE 7 标准 API 编写的代码必须能够针对兼容的服务器运行,否则 standard 这个词将没有任何意义。 Java的基本原则:一次编写,到处运行,应该是可以实现的。美中不足的是,当代码依赖于不属于标准的供应商特定功能时。还值得指出的是,TCK 不是免费的。事实上,我知道一个非常好的信息来源,他提到成本至少为 $250 K。因此, 进入的这个障碍超出了职权范围大多数开源项目或 Small &中型企业SME),没有来自天使或启动基金的大量投资。

2014 年初,甲骨文宣布将取消对 GlassFish 服务器的商业支持。这个消息让 Java EE 社区对应用程序服务器的未来充满了信心。 Oracle 后来澄清说 GlassFish 5 有一个路线图,它仍然在议程上,作为 Java EE 8 的参考实现。数据库供应商和 Java 管家反而建议升级到 Oracle WebLogic 用于生产的途径。 2014 年,Oracle 发布了带有选定的 Java EE 7 兼容组件的 WebLogic 12.1.3。

WildFly 9 (http://wildfly.org/) 是 Red Hat 的下一代应用服务器。 服务器采用模块化架构,基于新的类加载器基础设施,试图避免第三方 JAR 与内部基础设施之间的依赖冲突问题。服务器本身。 WildFly 有两个关键优势:新的高性能 HTTP 服务器,称为 Undertow (http://undertow.io/) 和减少管理端口。用于 Web 流量、Servlet、REST 和 WebSocket 端点的端口为 8080,用于服务器管理的端口为 9990。使用 WildFly,可以通过事实上的 HTTP 端口 8080 调用 EJB 远程方法,这为企业应用程序增加了一些有趣的可能性。

WildFly 9 中的模块化方法似乎适用于希望严格控制其企业架构部署的终端站点。 WildFly 有一个名为 core 发行版的下载选项,它允许开发人员在应用服务器运行时配置他们需要的模块。 WildFly 的最后一个好处是它是第一个与 Java SE 8(Lambda 和默认接口)兼容的 Java EE 7 服务器。只有 GlassFish 4.1 版本与 Java SE 8 兼容。

在 GlassFish 的专业支持失败后,另一家公司进入了该领域。 C2B2 Consulting 提供了 GlassFish 的开源改编版本,称为 Payara Server(http://payara.co.uk) 提供 24/7 生产支持。

我应该很快提到另一台服务器,它正在与服务器端 Java 社区取得联系,在不久的将来值得关注。 Apache 软件基金会有一个开源 项目,名为 Tom EE (http://tomee.apache.org/)。 Tom EE(发音为 Tommy)本质上是带有附加扩展的 Apache Tomcat 7,这些扩展已经配置,以支持 JSF、JPA JAX-RS、 CDI 和 EJB。 David Blevins 是一位受欢迎的演讲者和 ASF 提交者,他是 Tom EE 项目的创始人。在撰写本文时,Tom EE 仅通过 Java EE 6 Web Profile 认证;但是,有计划增加对 Java EE 7 的支持。业务利益相关者可以通过 Tomi Tribe (http://www.tomitribe.com/)。

由于 GlassFish、WildFly 和 Payara 是在 撰写本文时唯一被认证为符合 Java EE 7 的应用程序服务器,因此我们将只关注它们本书的其余部分。源代码示例适用于这两种服务器。如有必要,我们将指出差异并适当解释其功能。现在让我们继续使用 Java EE 7 进入数字 Web 之旅。

Summary


在本章中,我们讨论了数字工作者的角色,即您,工程师,以及您如何适应新的营销角色作为一个有创造力的人。我们研究了 2015 年和 2016 年肯定会出现的技能和工具链集。我们讨论了 Java 平台和 JVM 如何适应这幅图。

成为 Digital Java EE 7 工作者不仅仅是开发服务器端 Java 代码;您应该了解初级的 JavaScript 编程。你们中的一些人可能已经掌握了基本的 JavaScript 知识,而另一些人则对客户端空间中的编程有更多的了解。 JavaScript,尽管它的所有缺点和不幸,是一种值得尊重的专业语言,我们介绍了一些你应该知道的框架。虽然这本书没有教你 JavaScript,而是针对 Java EE 开发,但我建议你根据模块模式和应用高级库来复习你的技能。

在本章中,我们研究了 Java EE 7 架构和作为该平台一部分的规范。最后,我们仔细研究了一个简单的 JavaServer Faces 示例的代码。特别是,我们检查了 Facelet 视图代码。我们注意到大部分视图类似于标准 HTML。

在接下来的章节中,我们将深入研究 JSF 并构建一个简单的 Create Retrieve Update Delete (CRUD) 示例。我们将以几种不同的方式生成示例。俗话说,先爬后才能走,走后才能跑。我们的爬行结束了,现在让我们开始步行吧。

Exercises


为了帮助教育领域的人们:学生、教师和讲师,本书每章的末尾都提供了问题。

  1. 拿一张纸;概述核心 Java EE 7 规范,其中包括 Servlets CDI、EJB、JPA、JMS、JAX-RS 和 JSF。在 1-10 的范围内(1 是新手,10 是专家)问问自己,你真的知道多少?

  2. 您最后一次查看 Java EE 是什么时候?如果您仍将企业开发视为 J2EE 术语,那么您肯定需要看看这本书,Java EE 开发人员手册。记下您不太了解的规范并计划学习它们。

  3. 通过将规范的各个部分与您最近参与的 Web 应用程序相匹配,测试您对 Java EE 平台的理解。描述每个规范如何提供好处,包括提高生产力。

  4. 现在转而反对 Java EE。社区中有些声音支持标准化,有些则坚决反对标准化。批评者说,对于一个需要和创新的世界来说,标准化过程太慢了。您认为依赖 Java EE 平台的潜在缺陷是什么?想想软件开发以外的领域,例如教育、培训、招聘和更广泛的社区。 Java 的理想状态是什么,您可以做自己喜欢的事情并且无需承担任何责任?

  5. 您可能已经有一个喜欢的网站,您会定期访问,也许每天都会访问。画出或概述它的基本(高级)信息架构。您最喜欢的网站很有可能拥有丰富的内容并且已经存在了很长时间。您注意到您今天所知道的信息架构有哪些变化?

  6. 你的 JavaScript 知识有多好?在 1(初学者)和 10(专家)的等级上,您如何评价它作为一项技能?您的 JavaScript 与您的 Java 编程相比如何?

  7. 您知道吗,您可以使用开发者工具(Chrome 开发者工具 https://developer.chrome.com/devtools 或 Christopher Pederick 的 Web 开发工具 http://chrispederick.com/work/web-developer/ 或类似)?你有没有学会通过这些工具调试 JavaScript?为什么不学习简单地在代码中添加断点呢?使用检查器检查计算的 CSS 怎么样?

  8. 使用分布式版本控制系统 Git 从 GitHub (http:// github.com/peterpilgrim/digitaljavaee7),并检查本章给出的简单 JSF 示例周围的代码。下载并设置 GlassFish 4.1 (https://glassfish.java.net/) 或WildFly 9 (http://wildfly.org/) 应用服务器并运行第一个示例。

  9. 您在网页设计中的图像编辑技能有多好(使用商业应用程序 Adob​​e Photoshop 或 Firework 或 Xara Edit)?您是在工作中还是在家中参加这项活动,还是将这项工作委托给其他人,例如创意设计师?在这方面有更好的知识是否有利于您更广泛的职业计划?问问自己,这会让你成为一个更好的数字工作者吗?

  10. 实践敏捷软件开发的数字团队倾向于与利益相关者合作。幸运的是,他们与利益相关者直接接触。利益相关者是客户,是业务最终用户的代表,这些团队向其交付软件。您是否曾直接与利益相关者进行过对话?这些讨论的结果是什么?他们是怎么走的?你曾经希望更多地参与吗?你有没有想过要逃跑?回顾过去,你在这些会谈中的努力怎么能做得更好?设身处地为利益相关者着想,了解他对你的看法。