第二部分?Web层
第二部分 开始学习Web层技术
第三章 开始学习Web应用
Web应用是web服务器或者应用服务器的动态的扩展,其可分为以下两种:
■?????? 面向展现的: 一个面向展现的web应用生成可交互的web页面。可根据客户请求,返回包括多种类型的标记语言(例如HTML,XML等)的动态内容。第4章“Javaservlet 技术”到第15章“国际化与本地化的web应用”讲解了如何开发面向展现的web应用。
■?????? 面向服务的: 一个面向服务的web应用实现了web service的endpoint技术。面向展现的应用常常是面向服务应用的客户端。第16章“使用JAX-WS构建web应用”到第19章“带附件的SOAP消息 Java API”讲解了如何开发面向服务的web应用。
Web应用
在Java 2 平台,web组件为web服务器提供了动态的扩展能力。Web组件可以使servlet、JSP页面、或者web service endpoint。图3-1展现了这种web客户端和web应用之间的交互。客户端向web服务器发送http请求,web服务器实现了Java Servlet和JSP技术来把请求转换为 HTTPServletRequest对象。之后将对象转发给web组件,web组件则用这些对象与JavaBean组件或者数据库交互,并动态地生成内容。这些web组件之后生成HTTPServletResponse对象,或者将请求传递给其他web组件,并最终由某个web组件生成一个HTTPServletResponse对象。Web服务器再将此对象转换为HTTP相应并返回给客户端。
?
?
?
图3-1 Java Web 应用请求处理过程
?
Servlets 是Java语言编写的类文件,用以动态的生成处理请求并且生成响应。JSP 页面pages 是普通的文本文档,可被当做servlet来执行,但是使用更自然的方式来创建静态内容。虽然servlet和JSP页面可以互相替换地使用,但是也各有所长。Servlet最适合实现面向服务的应用(web service endpoint就是用servlet实现的),面向展现应用的控制功能,例如请求转发和处理非文本数据。JSP页面更适合生成本文标记语言,例如HTML,Scalable Vector Graphics (SVG), WirelessMarkup Language (WML), XML。
?
Java Servlet和JSP技术出现以后,相关的用于交互式web应用的Java技术和框架也被开发出来了。图3–2展示了这些技术及其之间的关系。
?
?图3–2?? ?Java Web 应用技术
?
请注意Java Servlet技术是所有web应用技术的基础,所以你应该熟读第4章的内容“Java Servlet技术”甚至如果你不打算编写servlet。每种技术都增加了一层凑想,来使web应用更加模板化,提高开发速度。同时也有利于维护、提高可扩展性和健壮性。
?
Web组件是由叫做web 容器(container)的运行平台服务来支持的。一个web容器提供诸如此类服务:请求转发,安全,并发,生命周期管理。他也为web组件提供命名、事务管理、邮件服务。
?
当应用安装(install)或者部署(deployed)到web容器时,某些的web应用可以配置其运行方式。配置信息保存在一个叫做web应用部署描述符? (web application deploymentdescriptor) (DD)的XML文本文档中。一个DD必须符合Java Servlet 规范中描述的schema定义。
?
本章提供了一个web应用开发涉及事项的概览。首先,概述了web应用的生命周期,之后描述了如何在应用服务器上打包及部署非常简单的web应用,然后讲述了配置应用服务器并讨论了如何指定最常用的配置参数。接下来提供了一个示例,Duke的书店。这个示例展现了Java EE web层的全部技术,并且描述了如何建立这个例子的共享组件。最后本章讨论了如何从web应用访问duke应用所需的数据库以及如何设置数据库资源。
?
Web应用生命周期
?
一个web应用由web组件、静态文件(例如图像)、辅助类文件及库文件组成。Web容器提供了多种支持服务,来增强web组件,并使其易于开发。然而,由于web应用必须利用这些服务,创建及运行web应用的过程也和传统的独立Java类的开发过程不同。
?
创建、部署、执行web应用的过程可以总结如下:
1. ?开发web组件代码
2. ?开发web应用部署描述符
3. ?编译web应用组件及组件用到的辅助类
4. ?将应用打包为一个可部署文件(可选)
5. ?将应用部署到web容器
6. ?访问指向web应用的URL
?
部署web组件代码将在后面几章讲述。第2步到第4步将在接下来的几节中,通过一个Hello World的面向展现的应用来讲解。该应用允许用户着在HTML表单(图 3–3)中输入一个人名,之后显示对此人的问候(图 3–4)。
?
图 3–3?? ?问候表单
?
?图 3–4? ?响应
?
这个Hello应用包括了两个web组件,用以生成问候语和响应。本章讨论了该应用的两个版本:一个JSP版本叫做hello1,此版本中组件是由两个JSP实现。(tut-install/javaeetutorial5/examples/web/hello1/web/index.jsp 和?tut-install/javaeetutorial5/examples/web/hello1/web/response.jsp)?另一个servlet版本叫做hello2,其组件是由两个servlet类实现。(tut-install/javaeetutorial5/examples/web/hello2/src/servlets/GreetingServlet.java 和?tut-install/javaeetutorial5/examples/web/hello2/src/servlets/ResponseServlet.java)?这两个版本都是用来展示如何打包、部署、配置以及运行包含这些组件的应用。第二章 “使用教学示例”说明了如何得到这些示例的代码。
?
在你安装完教学文件后,示例的源码就在下列目录:
■?????? ?tut-install/javaeetutorial5/examples/web/hello1/
■?????? ?tut-install/javaeetutorial5/examples/web/hello2/
?
?
Web模块
?
Java EE构架中,web组件和静态web内容文件(例如图像)叫做web 资源(resources).一个 web 模块(module) 则是最小的可部署的可用web资源。一个Java EE web模块符合Java Servlet规范中定义web 应用(application)的要求。
?
除了web组件和web资源,一个web模块还可能包括:
■? ??服务器端功能类(数据库bean, 购物车等)。通常这些类是符合JavaBean组件构架的。
■? ? 客户端功能类 (applet 和功能类)。
?
一个web模块有特定的结构。Web模块的顶层目录叫做应用的文档根目录(document root)。这个文档根目录是JSP页面,客户端(client-side)类文件及归档文件(archives)、静态web资源(例如图像)保存的地方。
?
这个文档根目录包括了一个叫做WEB-INF的子目录,其中包括以下文件:
■?? ??web.xml: web应用部署描述符
■?? ??标签库描述文件(Taglibrary descriptor)(参见第“标签库描述符”)
■?? ??classes文件夹: 一个包括服务器端类文件(server-side classes)的目录,包括servlet,功能类及JavaBean组件
■???? tag文件夹: 一个包括标签文件的目录。标签文件是标签库的实现。 (参看“标签文件位置”)
■?? ?? lib文件夹: A一个包括JAR归档文件的目录,其中的库文件是服务器端类文件。
?
如果你的web模块不包括任何servlet、过滤器或者监听器组件,那么他就不需要web部署描述符。换句话说,如果你的web模块只包括JSP和静态文件,那就不需要加入一个web.xml文件。将在 “Web模块打包”一节中讨论的,hello1示例,只包括JSP页面和图像,所以因此不需要加入一个部署描述符文件。
?
你也可以创建一个应用特定的子目录(即包目录)、使用文档根目录,或者使用WEB-INF/classes/ 目录。
?
一个web模块可以部署为未打包的文件结构,也可以部署为叫做WAR(web archive)的打包JAR文件。
?
要在应用服务器上部署一个WAR文件,文件必须包含一个运行时部署描述符,这个运行时部署描述符是一个XML文件,包括了以下信息:web应用上下文根(context root)、应用程序资源的可移植(portable)名称到应用服务器资源的映射。
?
这个叫做sun-web.xml的(应用服务器web应用)运行时部署描述符(DD)位于WEB-INF目录下,和web应用部署描述符放在一起。部署于应用服务器上的Web模块的结构见:图 3–5
?
图 3–5?? ?Web模块结构
?
Web模块打包
某些部署场合中以及你要分发web模块时,web模块就必须被打包成WAR文件。你可以通过在目录中执行jar命令来打包web模块,目录格式要符合web模块要求;你也可以使用Ant工具,或者使用你喜欢的IDE工具。本教程展示了如何使用NetBeans IDE或者Ant来构建、打包、部署同样的应用。
?
要使用NetBeans IDE构建hello1应用,按下述步骤即可:
1. ?选择 File→Open Project.
2. ?在Open Project 对话框,选择:
tut-install/javaeetutorial5/examples/web/
3. ?选择hello1文件夹
4. ?勾选Open as Main Project(作为主项目)复选框
5. ?点击Open Project
6. ?在Projects面板,右键点击hello1项目并选择Build
?
要使用Ant来构建hello1,按下述步骤即可:
1. ?在终端窗口,进入目录: tut-install/javaeetutorial5/examples/web/hello1/
2. ?输入ant. 这个命令会触发必要的编译,并将文件复制到
tut-install/javaeetutorial5/examples/web/hello1/build/ 目录,创建WAR文件并将其复制到tut-install/javaeetutorial5/examples/web/hello1/dist/目录。
?
部署WAR文件
?
你可以用以下几种方式将WAR文件部署到应用服务器:
■????????把WAR包复制到domain-dir/autodeploy/ 目录
■????????使用Admin Console
■????????使用asadmin或者ant来部署WAR包
■????????使用NetBeans IDE
?
所有这些方式都在本章有描述;但是整个教程中,你只会用到ant和NetBeans IDE来打包和部署。
?
设置上下文根(Context Root)
?
上下文根(context root) 用来在Java EE server中表示一个web应用。你部署web模块时,需要指定上下文根。一个上下文根必须以正斜线(forward slash) (/)开头,以字符串结尾。
?
在一个供应用服务器部署的打包web模块中,上下文根保存在sun-web.xml中。
?
要编辑上下文根,按下述步骤即可:
1. ?在NetBeans IDE的Project面板中打开你的项目
2. ?打开你项目的Web Pages和WEB-INF目录
3. ?双击sun-web.xml
4. ?在编辑面板,点击Edit As XML
5. ?编辑上下文根,其位于context-root元素之中
?
部署一个打包的Web模块
如果你已经部署过hello1应用,那在进行本节的部署操作之前,请先按照后面小结所讲内容卸载:“卸载Web模块” 。
?
使用Admin Console部署:
?
1. ?点开Applications节点
2. ?选择Web Applications节点
3. ?点击Deploy按钮
4. ?选中radio button:“Package file to be uploadedto the Application Server.”
5. ?输入WAR文件的全路径(或者点击Browse,通过浏览方式指定),并点击OK按钮
6. ?点击下一步Next.
7. ?输入application name(应用名称)
8. ?输入context root(上下文根)
9. ?勾选Enabled选项
10. 点击Finish按钮
?
?
使用asadmin部署:
?
要使用asadmin部署WAR包,打开终端窗口或者命令行窗口并执行:
?
asadmin deploy?full-path-to-war-file
?
?
使用Ant部署
?
要使用asadmin部署WAR包,打开终端窗口或者命令行窗口,进入你构建并打WAR包的目录,执行:
?
ant ?deploy
?
?
使用NetBeans IDE部署
?
要使用NetBeans IDE部署WAR包:
?
1. ?选择File→Open Project.
2. ?在Open Project对话框中,导航到(找到)你的项目,并打开它
3. ?在Projects选项卡,右键你的项目,选择Undeploy and Deploy.
?
?
?
测试已部署Web模块
?
现在web模块已经部署好了,你可在浏览器打开查看你的应用。默认情况下,应用部署在本机(localhost)的8080端口桑。此web应用的上下文根是hello1。
?
?
要测试部署的应用,执行以下步骤:
?
1. ?打开web浏览器
2. ?在地址栏输入如下地址:http://localhost:8080/hello1
3. ?输入你的名字,点击submit
?
应用就会如图 3–3、图 3–4所示,显示你提交的名字。
?
?
列出已部署Web模块
?
Application Server提供了两种方式来查看已部署web模块:
Admin Console和asadmin命令
?
使用Admin Console:
1.? 在浏览器打开地址:http://localhost:4848/asadmin
2.? 展开节点Applications→WebApplications.
?
使用asadmin命令:
asadmin list-components
?
?
更新Web模块
?
典型的迭代开发周期包括web模块部署及之后对应用组件的修改。要更新已部署web模块,必须执行以下步骤:
?
1. ?重新编译所有修改过的类文件
2. ?如果你部署的是一个打包的web模块,将更新WAR包内修改过的组件。
3. ?重新部署该模块
4. ?客户端重新载入URL
?
?
更新打包的Web模块
本节讲述了如何更新已打包的hello1 web模块
?
首先,修改下记文件中的问候语:
tut-install/javaeetutorial5/examples/web/hello1/web/index.jsp
?
<h2>Hi, my ?name is Duke. What’s yours?</h2>
?
?
要在NetBeans IDE中更新项目:
?
■?????? ?右键选择项目,点击Build.
■?????? ?右键选择项目,点击Undeployand Deploy.
?
要在Ant构建工具中更新项目:
?
■????? ??输入ant来将修改过的JSP页面复制到构建目录
■?????? ?输入ant deploy来部署WAR包
要查看修改过的模块,在浏览器重新载入URL即可。你就能在浏览器中看到图 3–6 。
?
?
图 3–6?? ?新的问候画面
?
动态重新载入(Dynamic Reloading)
?
如果动态重新载入是开启的状态,在你需要修改一些代码或者部署描述符时,你就不需要重新部署应用或者模块。你需要的只是将修改过的jsp或者class文件复制到应用(或模块)的部署目录下。名称为context-root的web模块的部署目录为:
domain-dir/applications/j2ee-modules/context-root 服务器定期检查有无修改,自动并动态地,并重新部署应用变更的部分。
?
这种功能在开发环境下十分实用,因为这样就可以在修改代码后快速测试。动态载入并不推荐在生产环境使用,因为他可能会影响性能。另外,当重新载入完成后,seesion也会失效,客户端必须重新开始一个会话(session)。
?
?
要启用动态重载,打开Admin Console:
?
1. ?选择Applications Server节点
2. ?选择Advanced选项卡
3. ?勾选Reload Enabled以启用动态重新加载
4. ?在Reload Poll Interval字段,输入一个秒数,以设定应用和模块检查代码变化和自动重新载入的时间间隔。
5. ?点击Save按钮
?
另外,要加载新的servlet文件或者部署描述符变更时,必须执行如下步骤:
?
1. ?在模块的根目录创建一个名为.reload的空文件
domain-dir/applications/j2ee-modules/context-root/.reload
2. ?在每次修改(servlet或DD)时,显式地更新.reload文件的时间戳。在UNIX上,执行:
?
touch .reload
?
对于JSP页面,更新和重载入的频率由上述Reload Poll Interval决定。要禁用JSP页面的自动重新载入,将Reload Poll Interval字段的值置为 -1 即可。
?
?
卸载 Web模块
?
有四种方式来卸载应用:NetBeans IDE, Admin Console,asadmin命令, Ant工具。
?
使用NetBeans IDE:
1.? 确认Application Server正在运行
2.? 在Runtime窗口,展开Application Server实例及包含应用(或模块)的节点
3.? 右键应用或模块,选择Undeploy
?
使用Admin Console:
1.? 浏览器中打开地址:http://localhost:4848/asadmin
2.? 展开Applications节点
3.? 选择Web Applications
4.? 勾选你要卸载的应用(勾选应用后的check box)
5.? 点击Undeploy按钮
?
使用asadmin命令:
asadmin undeploy context-root
?
要使用Ant工具,在你 构建并打WAR包的目录下,执行此命令即可:
?
ant ?undeploy
?
配置Web应用
?
你可通过web应用部署描述符中包含的元素来配置Web应用。
?
后面小节会为web应用的常用配置做一个简述。一些可配置的安全参数,参见第30章 “保证Web应用安全”
?
下面的小节中,例子演示了配置Hello, World应用的步骤。对于Hello, World没有用到的特别配置,本节也会推荐其他(章节的)示例,来演示如何指定该部署描述符元素。
?
?
将URL映射到Web组件
?
当web容器收到一个请求时,容器必须决定由哪个web组件来处理此请求。其通过将请求中URL和web应用及组件相匹配来是实现。一个URL路径包含了上下文根(context root)和一个别名(alias):
?
http://host:port/context-root/alias
?
?
设置组件别名(Alias)
别名(alias) 标示了应该处理请求web组件。别名路径必须以正斜线(/)(forward slash)开头,以字符串或者带扩展名的通配符结束 (例如*.jsp) 。由于web容器会自动匹配以*.jsp结尾的别名,所以你不需要为JSP页面指定别名,除非你不想根据jsp的文件名来引用页面。(unless you wish to refer to the page by aname other than its file name.)
?
hello2 应用有连个servlet需要配置到web.xml文件中,你可以在NetBeans IDE中通过如下方式来编辑web.xml文件:
?
1.? 选择File→Open Project.
2.? 在Open Project对话框,导航到:
?
tut-install/javaeetutorial5/examples/web/
3.? 选择hello2文件夹
4.? 勾选Open as Main Project选项
5.? 点击Open Project.
6.? 在Projects面板展开项目树
7.? 在项目树中展开Web pages节点,并打开WEB-INF节点
8.? 双击WEB-INF节点中的web.xml
(翻到这真想吐槽啊,把人都当傻子了啊有木有~~)
?
下述步骤描述了如何对web.xml文件进行必要的修改,包括如何设置显示名称、如何映射servlet组件。因为编辑内容已经写在文件里了,你可以按些步骤下看看设置就行。
?
设置显示名称:
?
1. ?点击编辑器顶部的General,打开通用配置
2. ?在Display Name字段输入hello2
进行servlet映射配置:
?
1.? 点击编辑器顶部的Servlets,打开Servlet配置
2.? 点击Add Servlet.
3.? 在Add Servlet对话框Servlet Name字段输入GreetingServlet
4.? 在Servlet Class字段输入servlets.GreetingServlet
5.? 在URL Pattern字段输入 /greeting
6.? 点击OK.
7.? 重复以上步骤,只是把servlet name替换为ResponseServlet ,servlet class替换为servlets.ResponseServlet, URL pattern替换为/response。
?
如果你没使用NetBeans IDE,你也可以用一个文本编辑器里添加这些设置。
?
要用NetBeans IDE打包此实例,按以下步骤:
?
1.? 选择 File→Open Project.
2.? 在Open Project对话框,导航到
tut-install/javaeetutorial5/examples/web/
3.? 选择hello2文件夹
4.? 勾选Open as Main Project
5.? 点击Open Project
6.? 在Projects选项卡,右键hello2项目,选择Build.
要用Ant打包此实例,按以下步骤:
1. ?在终端窗口,进入目录:?tut-install/javaeetutorial5/examples/web/hello2/.
2. ?输入ant. 此target会构建WAR包并将其复制到下记目录:
tut-install/javaeetutorial5/examples/web/hello2/dist/
?
要使用NetBeans IDE部署本示例,右键项目面板中的项目,然后选择Undeploy and Deploy。
?
要使用Ant部署本示例,输入 ant deploy. The deploy target in this case gives you an incorrect URL to run the application. To run the application, please use the URL shown at the end of this section.
?
要运行本应用,先部署此web模块,然后在浏览器中打开URL:
http://localhost:8080/hello2/greeting