创建和发布web应用--tomcat

上一篇 / 下一篇  2009-07-08 14:51:24 / 个人分类:Apache

本章介绍如何在Tomcat上创建和发布Web应用。这里首先讲解Tomcat的目录结构以
及Web应用的目录结构,接着介绍如何将HTML、Servlet、JSP和Tag Library部署到Web
应用中,然后介绍把整个Web 应用打包并发布的方法,最后介绍如何在Tomcat 上配置虚
拟主机。
本章侧重于讨论Web 应用的结构和发布方法,所以没有对本章的Servlet 和JSP 的例
子进行详细解释,关于Servlet和JSP的技术可以分别参考第3 章和第4 章的内容。
2.1 Tomcat 的目录结构
在 Tomcat上发布Web应用之前,首先要了解Tomcat 的目录结构。Tomcat的目录结构
参见表2-1,这些目录都是<CATALINA_HOME>的子目录。
表2-1 Tomcat的目录结构
 目录描述
 /bin 存放在Windows平台以及Linux平台上启动和关闭Tomcat的脚本文件
 /conf 存放Tomcat 服务器的各种配置文件,其中最重要的配置文件是server.xml
 /server 包含3 个子目录: classes、lib和webapps
 /server/lib 存放Tomcat 服务器所需的各种JAR 文件
/server/webapps
存放Tomcat 自带的两个Web应用: admin应用和manager应用
 /common/lib 存放Tomcat 服务器以及所有Web应用都可以访问的JAR 文件
 /shared/lib 存放所有Web应用都可以访问的JAR 文件
 /logs 存放Tomcat 的日志文件
 /webapps 当发布Web应用时,默认情况下把Web应用文件放于此目录下
 /work Tomcat 把由JSP 生成的Servlet 放于此目录下

从表2-1 可以看出,在/server/lib 目录、/common/lib 和/shared/lib 目录下都可以放JAR
文件,它们的区别在于:
l 在/server/lib 目录下的JAR文件只可被Tomcat服务器访问
l 在/shared/lib 目录下的JAR 文件可以被所有的Web 应用访问,但不能被Tomcat
服务器访问
l 在/common/lib 目录下的JAR文件可以被Tomcat服务器和所有Web应用访问
此外,对于下面将要介绍的Java Web应用,在它的WEB-INF目录下,也可以建立lib
子目录,在lib 子目录下可以放各种JAR文件,这些JAR文件只能被当前Web 应用访问。
(在以上提到的lib 目录下都只接受JAR文件,如果类压缩文件为ZIP文
件,应该将它展开,重新打包为JAR文件再拷贝到lib 目录中。如果直接将
ZIP文件拷贝到lib 目录,则会发现Tomcat服务器仍然找不到相关的类。打
包命令参见2.2.8 节。)
2.2 创建和发布 Web 应用
Java Web应用由一组静态HTML页、Servlet、JSP和其他相关的class组成。每种组件
在Web应用中都有固定的存放目录。Web应用的配置信息存放在web.xml文件中。在发布
某些组件(如Servlet)时,必须在web.xml文件中添加相应的配置信息。
2.2.1 Web应用的目录结构
Web应用具有固定的目录结构,假定开发一个名为helloapp的Web应用。首先,应该
在<CATALINA_HOME>/webapps目录下创建这个Web应用的目录结构,参见表2-2。
表2-2 Web应用的目录结构
 目录描述
 /helloapp Web应用的根目录,所有的JSP 和HTML 文件都存放于此目录
 /helloapp/WEB-INF 存放Web应用的发布描述文件web.xml
 /helloapp/WEB-INF/classes 存放各种class文件,Servlet 类文件也放于此目录下
 helloapp/WEB-INF/lib/ 存放Web应用所需的各种JAR文件。例如,在这个目录下,可以存放JDBC
驱动程序的JAR 文件

从表2-2 中,我们看到在classes 以及lib 子目录下,都可以存放Java 类文件。在运行
过程中,Tomcat 的类装载器先装载classes 目录下的类,再装载lib 目录下的类。因此,如
果两个目录下存在同名的类,classes目录下的类具有优先权。
本章介绍的 helloapp 应用的目录结构如图2-1 所示,helloapp 应用在Windows 资源管
理器中的展开如图2-2所示。
在helloapp应用中创建了如下组件:
l  HTML组件:index.htm
l  JSP组件:login.jsp和hello.jsp
l  Servlet组件:DispatcherServlet
这些组件之间的链接关系为:
index.htm→login.jsp→DispatcherServlet→hello.jsp






2.2.2 web.xml文件
Java Web 应用通过一个基于XML 的发布描述符文件来配置其发布信息,这个文件名
为web.xml,它存放于WEB-INF子目录下。在附录B中将详细介绍web.xml的配置方法,
在附录C中将介绍XML的基本知识。在web.xml文件中可包含如下配置信息:
l  Servlet的定义
l  Servlet的初始化参数
l  Servlet以及JSP的映射
l  安全域配置参数
l  welcome文件清单
l 资源引用
l  环境变量的定义
现在,创建一个默认的web.xml文件,并把这个文件放到WEB-INF目录中。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
'-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
'http://java.sun.com/j2ee/dtds/web-app_2_3.dtd'>
<web-app>
</web-app>
以上web.xml 文件的第一行指定了XML 的版本和字符编码,第二行DOCTYPE 指定
文档类型,接下来声明了一个<web-app>元素,所有关于Web 应用的配置元素都将加入到
这个<web-app>元素中。
2.2.3 在server.xml中加入<Context>元素
<Context>元素是<CATLINA_HOME>/conf/server.xml 中使用最频繁的元素,它代表了
运行在<Host>上的单个Web 应用。一个<Host>中可以有多个<Context>元素。每个Web 应
用必须有惟一的URL路径,这个URL路径在<Context>元素的path属性中设定。
例如,在名为“localhost”的<Host>元素中加入如下<Context>元素:
<!-- Define the default virtual host -->
<Host name="localhost" debug="0" appBase="webapps"
unpackWARs="true" autoDeploy="true">
……
……
<Context path="/helloapp" docBase="helloapp" debug="0"
reloadable="true"/>
</Host>
Context元素的各个属性的说明参见表2-3。
表2-3 Context元素的属性
 属性描述
 path 指定访问该Web应用的URL 入口
 docBase 指定Web 应用的文件路径,可以给定绝对路径,也可以给定相对于Host 的appBase 属性的相对路径
(关于Host 的appBase 属性参见2.3 节)。如果Web应用采用开放目录结构,则指定Web应用的根目录;
如果Web应用是个WAR 文件,则指定WAR 文件的路径
reloadable
如果这个属性设为true,Tomcat 服务器在运行状态下会监视在WEB-INF/classes 和WEB-INF/lib 目录
下class文件的改动。如果监测到有class文件被更新,服务器会自动重新加载Web应用

(在开发阶段,将reloadable属性设为true,有助于调试Servlet和其他的
class 文件。但是由于这一功能会加重服务器的运行负荷,因此建议在Web
应用的产品发布阶段,将这个属性设为false。)

2.2.4 部署HTML文件
在 helloapp 目录下加入index.htm 文件,这个文件仅仅用来显示一串带链接的字符
“Welcome to HelloApp”, 它链接到login.jsp文件。以下是index.htm文件的代码:
<html>
  <head>
    <title>helloapp</title>
  </head>
  <body >
    <p><font size="7">Welcome to HelloApp</font></p>
    <p><a href="login.jsp?language=English">English version </a>
  </body>
</html>
访问index.htm 的URL 为http://localhost:8080/helloapp/index.htm,该页面的显示结果
如图2-3所示。
图2-3 :

2.2.5 部署JSP
接下来,创建两个JSP文件,其中一个是login.jsp(参见例程2-1),它显示登录页面,
要求输入用户名和口令,这个页面链接到一个名为DispatcherServlet的Servlet。还有一个
JSP文件是hello.jsp(参见例程2-2),这个JSP被DispatcherServlet调用,显示Hello页面。
JSP 的语法将在第4 章详细讨论,本节侧重于介绍JSP 的发布过程。这两个JSP 文件都应
放在helloapp目录下。
例程2-1 login.jsp:
<html>
     <head>
        <title>helloapp</title>
     </head>
     <body >
        <br>
        <form. name="loginForm" method="post" action="dispatcher">
           <table>
              <tr>
                  <td><div align="right">User Name:</div></td>
                  <td> <input type="text" name="username"></td>
              </tr>
              <tr>
                  <td><div align="right">Password:</div></td>
                  <td><input type="password" name="password"></td>
              </tr>
              <tr>
                  <td></td>
                  <td><input type="Submit" name="Submit" value="Submit"></td>
              </tr>
            </table>
          </form>
        </body>
</html

例程2-2 hello.jsp:
<html>
   <head>
      <title>helloapp</title>
   </head>
   <body>
      <b>Welcome: <%= request.getAttribute("USER") %></b>
   </body>
</html>
login.jsp 中生成了一个loginForm表单,它有两个字段:username 和passoword。访问
login.jsp的URL为http://localhost:8080/helloapp/login.jsp,它生成的页面如图2-4所示。
图2-4 login.jsp网页

2.2.6 部署Servlet
下面,创建一个Servlet 文件,名为DispatcherServlet.java(参见例程2-3),它调用
HttpServletRequest对象的getParameter 方法读取客户提交的loginForm表单数据,获取用户
名和口令,然后将用户名和口令保存在HttpServletRequest对象的属性中,再把请求转发给
hello.jsp。
例程2-3 DispatcherServlet.java
package mypack;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class DispatcherServlet extends HttpServlet {
private String target = "/hello.jsp";
public void init(ServletConfig config)
throws ServletException {
super.init(config);
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// If it is a get request forward to doPost()
doPost(request, response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Get the username from the request
String username = request.getParameter("username");
// Get the password from the request
String password = request.getParameter("password");
// Add the user to the request
request.setAttribute("USER", username);
request.setAttribute("PASSWORD", password);
// Forward the request to the target named
ServletContext context = getServletContext();
System.out.println("Redirecting to " + target);
RequestDispatcher dispatcher =
context.getRequestDispatcher(target);
dispatcher.forward(request, response);
}
public void destroy() {
}
}

编译并发布DispatcherServlet的步骤如下。
(1)编译DispatcherServlet.java。编译时,需要将Java Servlet API 的JAR 文件
(servlet-api.jar)设置为classpath,servlet-api.jar 文件位于<CATALINA_HOME>/common/lib
目录下。
( 2 ) 把编译出来的class 文件拷贝到/helloapp/WEB_INF/classes 目录下。
DispatcherServlet.class的存放位置为/helloapp/WEB_INF/classes/mypack/DispatcherServlet。
在本例中,声明将DispatcherServlet 类放在包mypack 下,所以应该在
/WEB_INF/classes 目录下先创建子目录/mypack,然后在子目录下放
DispatcherServlet.class文件。
(3)接下来在web.xml中为DispatcherServlet类加上<servlet>和<servlet-mapping>元素。
<web-app>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>mypack.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/dispatcher</url-pattern>
</servlet-mapping>
</web-app>
<servlet>元素的属性描述参见表2-4。
在本例配置中,没有为DispatcherServlet设置load-on-startup属性,因此当Web应用启
动时,Servlet 容器不会加载这个Servlet,只有当Web 客户首次访问这个Servlet 时才加载
它。
表2-4 <servlet>元素的属性:
属性
说明
 <servlet-name> 定义Servlet 的名字
 <servlet-class> 指定实现这个Servlet 的类
<init-param>
定义Servlet 的初始化参数(包括参数名和参数值),一个<servlet>元素中可以有
多个<init-param>
<load-on-startup>
指定当Web 应用启动时,装载Servlet 的次序。当这个值为正数或零,Servlet 容
器先加载数值小的Servlet,再依次加载其他数值大的Servlet。如果这个值为负数或
者没有设定,那么Servlet 容器将在Web客户首次访问这个Servlet 时加载它

<servlet-mapping>元素用来指定<servlet-name>和<url-pattern>映射。<url-pattern>是指访
问Servlet的相对URL路径。
根据以上<url-pattern>属性,访问DispatcherServlet 的URL 为http://localhost:8080/
helloapp/dispatcher,DispatcherServlet接受到客户请求后,再把请求转发给hello.jsp,hello.jsp
生成的页面如图2-5所示。
图2-5 DispatcherServlet调用hello.jsp生成的网页
2.2.7 部署JSP Tag Library
最后,在Web应用中加入Tag Library(标签库)。Tag Library向用户提供了自定义JSP
标签的功能。我们将定义一个名为mytaglib 的标签库,它包含了一个简单的hello标签,这
个标签能够将JSP页面中所有的<mm:hello/>解析为字符串“hello”。
以下是创建和发布mytaglib 标签库的步骤。
(1)编写用于处理hello 标签的类HelloTag.java,例程2-4 列出了HelloTag.java 的源
代码。
例程2-4 HelloTag.java
package mypack;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
public class HelloTag extends TagSupport
{
public void HelloTag() { }
// Method called when the closing hello tag is encountered
public int doEndTag() throws JspException {
try {
// We use the pageContext to get a Writer
// We then print the text string Hello
pageContext.getOut().print("Hello");
}
catch (Exception e) {
throw new JspTagException(e.getMessage());
}
// We want to return SKIP_BODY because this Tag does not support
// a Tag Body
return SKIP_BODY;
}
public void release() {
// Call the parent's release to release any resources
// used by the parent tag.
// This is just good practice for when you start creating
// hierarchies of tags.
super.release();
}
}

编译HelloTag.java 时,需要将jsp-api.jar 文件添加到classpath中,这个JAR文件位于
<CATALINA_HOME>/common/lib 目录下。编译生成的HelloTag.class 存放位置为
/WEB-INF/classes/mypack/HelloTag.class。
(2)创建Tag Library的描述文件mytaglib.tld文件,在这个文件中定义mytaglib 标签
库和hello标签。这个文件存放位置为/WEB-INF/mytaglib.tld。例程2-5 列出了mytaglib.tld
的源代码。
例程2-5 mytaglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<!-- a tag library descriptor -->
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>mytaglib</shortname>
<uri>/mytaglib</uri>
<tag>
<name>hello</name>
<tagclass>mypack.HelloTag</tagclass>
<bodycontent>empty</bodycontent>
<info>Just Says Hello</info>
</tag>
</taglib>
(3)在web.xml文件中加入<taglib>元素,例程2-6列出了修改后的web.xml文件。
例程2-6 加入<taglib>元素的web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
'-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
'http://java.sun.com/j2ee/dtds/web-app_2_3.dtd'>
<web-app>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>mypack.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/dispatcher</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>/mytaglib</taglib-uri>
<taglib-location>/WEB-INF/mytaglib.tld</taglib-location>
</taglib>
</web-app>
<taglib>中包含两个属性<taglib-uri>和<taglib-location>。其中<taglib-uri>指定Tag
Library标示符;<taglib-location>指定Tag Library的描述文件(TLD)的位置。
(4)在hello.jsp文件中加入hello标签。首先,在hello.jsp中加入引用mytaglib 的taglib
指令:
<%@ taglib uri="/mytaglib" prefix="mm" %>
以上taglib 指令中,prefix 用来指定引用mytaglib标签库时的前缀,修改后的hello.jsp
文件参见例程2-7。
例程2-7 加入Tag标签的hello.jsp
<%@ taglib uri="/mytaglib" prefix="mm" %>
<html>
<head>
<title>helloapp</title>
</head>
<b><mm:hello/> : <%= request.getAttribute("USER") %></b>
</body>
</html>
hello.jsp 修改后,再依次访问index.htm→login.jsp→DispatcherServlet→hello.jsp,最后
生成的网页如图2-6所示。
图2-6 带hello标签的hello.jsp生成的网页
2.2.8 创建并发布WAR文件
Tomcat既可以运行采用开放式目录结构的Web应用,也可以运行WAR文件。在本书
配套光盘的sourcecode/chapter2/helloapp目录下提供了所有源文件,只要把整个helloapp目
录拷贝到<CATALINA_HOME>/webapps目录下,即可运行开放式目录结构的helloapp应用。
在 Web应用的开发阶段,为了便于调试,通常采用开放式的目录结构来发布Web应用,
这样可以方便地更新或替换文件。如果开发完毕,进入产品发布阶段,应该将整个Web 应
用打包为WAR文件,再进行发布。
在本例中,按如下步骤发布helloapp。
步骤:
(1)进入helloapp应用的根目录<CATALINA_HOME>/webapps/helloapp。
(2)把整个Web应用打包为helloapp.war 文件,命令如下:
jar cvf helloapp.war *.*
(在 JDK 的bin 目录下提供了打包程序jar.exe。如果要展开helloapp.war
文件,命令为: jar xvf helloapp.war。)
(3)把helloapp.war 文件拷贝到<CATALINA_HOME>/webapps目录下。
(4)删除原先的helloapp目录。
(5)启动Tomcat服务器。
Tomcat 服务器启动时,会把webapps 目录下的所有WAR 文件自动展开为开放式的目
录结构。所以服务器启动后,会发现服务器把helloapp.war 展开到<CATALINA_HOME>
/webapps/helloapp目录中。
2.3 配置虚拟主机
在 Tomcat 的配置文件server.xml 中,Host 元素代表虚拟主机,在同一个Engine 元素
下可以配置多个虚拟主机。例如,有两个公司的Web 应用都发布在同一个Tomcat 服务器
上,可以为每家公司分别创建一个虚拟主机,它们的虚拟主机名分别为:
www.mycompany1.com
www.mycompany2.com
这样当Web客户访问以上两个Web应用时,就好像这两个应用分别拥有各自的主机。
此外,还可以为虚拟主机建立别名,例如,如果希望Web客户访问www.mycompany1.com
或mycompany1.com都能连接到同一个Web,那么可以把mycompany1.com 作为虚拟主机
的别名来处理。
下面讲解如何配置www.mycompany1.com虚拟主机。
步骤:
(1)打开<CATALINA_HOME>/conf/server.xml 文件,会发现在<Engine>元素中已经
有一个名为localhost 的<Host >元素,可以在它的后面(即</Host>后面)加入如下<Host>
元素:
<Host name="www.mycompany1.com" debug="0" appBase="C:\mycompany1"
unpackWARs="true" autoDeploy="true">
<alias>mycompany1.com</alias>
<alias>mycompany1</alias>
<Context path="/helloapp" docBase="helloapp" debug="0"
reloadable="true" />
</Host>
(以上配置代码位于本书配套光盘的sourcecode/chapter2/virtualhost-configure.xml 文件
中。)
<Host>元素的属性描述参见表2-5。
表2-5 <Host>元素的属性
 属性描述
 name 指定虚拟主机的名字
 debug 指定日志级别
appBase
指定虚拟主机的目录,可以指定绝对目录,也可以指定相对于<CATALINA_HOME>的相对
目录。如果此项没有设定,默认值为<CATALINA_HOME>/webapps
unpackWARs
如果此项设为true,表示将把Web 应用的WAR 文件先展开为开放目录结构后再运行。如
果设为false,则直接运行WAR 文件
autoDeploy
如果此项设为true,表示当Tomcat 服务器处于运行状态时,能够监测appBase 下的文件,
如果有新的Web应用加入进来,则会自动发布这个Web应用
alias
指定虚拟主机的别名,可以指定多个别名
deployOnStartup
如果此项设为true,则表示Tomcat 服务器启动时会自动发布appBase 目录下所有的Web应
用。如果Web应用在server.xml 中没有相应的<Context>元素,则将采用默认的Context 配置。
deployOnStartup的默认值为true

在<Host>的deployOnStartup 属性为true 的情况下,即使你没有在server.xml 中为
helloapp应用加入<Context>元素,Tomcat服务器也可以自动发布和运行helloapp应用。在
这种情况下,Tomcat使用默认的DefaultContext。关于DefaultContext的知识可以参考Tomcat
文档:
<CATALINA_HOME>/webapps/tomcat-docs/config/defaultcontext.html
(2)把helloapp 应用(helloapp.war 文件或者是整个helloapp 目录)拷贝到appBase
属性指定的目录C:\mycompany1 下。
(3)为了使以上配置的虚拟主机生效,必须在DNS 服务器中注册以上的虚拟主机名
和别名,使它们的IP地址都指向Tomcat服务器所在的机器。必须注册以下名字:
www.mycompany1.com
mycompany1.com
mycompany1
(4)重启Tomcat服务器,然后通过浏览器访问:
http://www.mycompany1.com/helloapp/index.htm
如果返回正常的页面就说明配置成功。还可以通过虚拟机的别名来访问helloapp应用:
http://mycompany1.com/helloapp/index.htm
http://mycompany1/helloapp/index.htm

2.4 小 结
本章通过helloapp Web 应用例子,介绍了在Tomcat 上创建和发布Web 应用的步骤。
通过本章内容,读者可以学会创建Web应用的目录结构,创建web.xml文件,并且能够把
HTML、Servlet、JSP和Tag Library部署到Web应用中。此外,读者还可以掌握将整个Web
应用打包并发布的方法。本章还介绍了配置虚拟主机的方法。
为了便于读者编译源程序,在本书配套光盘的sourcecode/chapter2 目录下提供了编译
本章Java 程序的脚本compile.bat,它的内容如下:
set catalina_home=C:\jakarta-tomcat
set path=%path%;C:\j2sdk1.4.2\bin
set currpath=.\
if "%OS%" == "Windows_NT" set currpath=%~dp0%
set src=%currpath%helloapp\src
set dest=%currpath%helloapp\WEB-INF\classes
set classpath= %catalina_home%\common\lib\servlet-api.jar;
%catalina_home%\common\lib\jsp-api.jar
javac -sourcepath %src% -d %dest% %src%\mypack\DispatcherServlet.java
javac -sourcepath %src% -d %dest% %src%\mypack\HelloTag.java
运行这个脚本时,只要重新设置以上Tomcat目录和JDK 的目录即可。
在 javac 命令中,-sourcepath 设定Java 源文件的路径,-d 设定编译生成的类的存放路
径。javac 命令的-classpath 参数可以设定classpath 路径,如果此项没有设定,将参照环境
变量classpath的设置。

TAG:

 

评分:0

我来说两句

日历

« 2024-05-04  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 58112
  • 日志数: 89
  • 建立时间: 2008-12-13
  • 更新时间: 2010-01-13

RSS订阅

Open Toolbar