今天有点需求,需要用jasper-runtime.jar包。但是我在我的/apache-tomcat-6.0.16/lib目录下,怎么也找不到这个jar包。结果上网百度了一下。Tomcat6.0之前的版本以Tomcat5.5.20 压缩版为例,这个jasper-runtime.jar在Tomcat5.5.20/common/lib下就自带有的。但是在Tomcat6.0版本后lib包的位置调整了,现在只有lib在跟目录下。jasper-runtime.jar和jasper-compiler-jdt.jar、jasper-compiler.jar等都集成到jasper.jar包中去了。
顺便说一下tomcat下各个目录:
/bin:存放启动和关闭tomcat的脚本文件;
/conf:存放tomcat的各种配置文件,比如:server.xml
/server/lib:存放tomcat服务器所需要的各种jar文件(jar文件只可被tomcat 服务器访问)
/server/webapps:存放tomcat自带的两个web应用:admin应用和manager应用。
/common/lib:存放tomcat服务器以及所有web应用都可以访问的jar文件夹(web和tomcat服务器都可访问此jar)
/shared/lib:存放web都可访问的jar文件。(可以被所有的web访问,但不能被tomcat访问)
/logs:存放tomcat的日志文件
/webapps:当发布web应用时,默认情况下把web应用文件放于此目录下
/work:tomcat把由jsp生成的Servlet放于此目录
另:在web应用中,WEB-Inf目录下,也可以建立lib子目录,在此子目录下可以存放各种jar文件,这些jar文件只能被当前web应用访问。其中,在web-inf目录下的lib与classes目录,Tomcat类装载器先装载classes目录下的类,再装载lib目录下的类。因为类同名时,classes优先。
其中jsp运行时,查找class的顺序为:项目文件夹(WEB-INF/lib)===》容器文件夹(tomcat/common/lib)==》jdk文件夹(jdk/jre/lib/ext)
Tomcat的配置文件
Tomcat的配置基于两个配置文件:
1.server.xml - Tomcat的全局配置文件
2.web.xml - 在Tomcat中配置不同的关系环境
server.xml
server.xml是Tomcat的主配置文件.完成两个目标:
1 提供Tomcat组件的初始配置.
2 说明Tomcat的结构,含义,使得Tomcat通过实例化组件完成起动及构建自身, 如在server.xml所指定的
server.xml种的重要元素:
元素及其描述
Server
server.xml文件中最重要的元素.Server定义了一个Tomcat服务器.一般你不用对他担心太多.Server元素能包含Logger和ContextManager元素类型
Logger
此元素定义一个Logger对象,每个Logger都有一个名字去标识,也有一个纪录Logger的输出和冗余级别(描述此日志级别)和包含日志文件的路径.通常有servlet的Logger(ServletContext.log()处),JSP和Tomcat运行时的Logger,
ContextManager
ContextManager说明一套ContextInterceptor, RequestInterceptor , Context和他们的Connectors的配置及结构.ContextManager有几个随同提供的特性:
1. 用来纪录调试信息的调试级别
2. webapps/,conf/,logs/和所有已定义的环境的基本位置.用来使Tomcat可以在TOMCAT_HOME外的其他目录启动.
3. 工作目录的名字
ContextInterceptor&RequestInterceptor
这些侦听器(interceptors)侦听具体发生在ContextManager中的事件.例如,ContextInterceptor侦听Tomcat的启动及终止事件,RequestInterceptor监视在它服务过程中用户请求需要通过的不同阶段.Tomcat的管理员不必知道太多关于侦听器的知识;另外,开发者应该知道这是如何在Tomcat中实现一个”全局”型的操作(例如安全性及每个请求日志)
Connector
Connector表示一个到用户的联接,不管是通过web服务器或直接到用户浏览器(在一个独立配置中).Connector负责管理Tomcat的工作线程和 读/写 连接到不同用户的端口的 请求/响应.Connector的配置包含如下信息:
1.句柄类
2.句柄监听的TCP/IP端口
3.句柄服务器端口的TCP/IP的backlog.
Context
每个Context提供一个指向你放置你Web项目的Tomcat的下属目录。每个Context包含如下配置:
1. Context放置的路径,可以是与ContextManager主目录相关的路径.
2.纪录调试信息的调试级别
3.可重载的标志.开发Servlet时,重载更改后的Servlet,这是一个非常便利的特性,你可以调试或用Tomcat测试新代码而不用停止或重新启动Tomcat.要打开重载,把reloadable设为真即可.这虽花费时间但可检测所发生的变化;更重要的事,鉴于,在一个装载类对象装入一个新的servlet时,类装载触发器可能会掷出一些错误.为避免这些问题,你可以设置可重载为假,这将停止重载功能.
web.xml
Tomcat可以让用户通过将缺省的web.xml放入conf目录中来定义所有关系环境的web.xml的缺省值.建立一个新的关系环境时,Tomcat使用缺省的web.xml文件作为基本设置和应用项目特定的web.xml(放在应用项目的WEB-INF/web.xml文件)来覆盖这些缺省值.
Tomcat server 配置节点说明
1.1 Server
Server代表整个Catalina servlet容器。在server.xml配置文件中必须是顶层元素且唯一,给它配置的属性代表整个容器的属性。
1.2 Service
Service是这样一个集合:它由一个或者多个Connector,以及一个共享的处理引擎(Engine)组成。Engine负责处理所有Connector所获得的客户请求。
1.3 Connector
一个连接器(Connector)将在某个指定端口上侦听客户请求,并将获得的请求交给Engine来处理,从Engine处获得响应结果,并返回给客户端。
Tomcat有两个典型的连接器,一个直接侦听来自客户端浏览器的http请求,一个侦听来自其它Web服务器的请求。
Coyote Http/1.1 Connector 在端口8080处侦听来自客户浏览器的http请求,Coyote JK2 Connector 在端口8009处侦听来自其它Web服务器(比如Apache)的servlet/jsp代理请求。当使用Coyote Http/1.1 Connector时,Tomcat作为独立的Web容器,同时扮演Web服务器和Servlet容器的双重角色。当使用Coyote JK2 Connector时,Tomcat只扮演Servlet容器的角色,Web服务器则由Apache或者其他服务器来提供,由于这些专有的Web服务器在处理静态资源的性能和效率上要比Tomcat提供的Web服务器要好,所以很多人将Tomcat和Apache配合使用。
1.4 Engine
处理引擎(Engine)代表一个Service所属的请求处理机,它接受所有连接器传递过来的客户端请求,将处理结果返回给连接器,由连接器将最终响应返回给客户端。Engine必须配置在Service组件下。处理引擎下可以配置多个虚拟主机(Virtual Host),每个虚拟主机都有一个域名。当处理引擎获得一个请求时,它把该请求匹配到某个虚拟主机上,把请求交给该虚拟主机来处理。处理引擎有一个默认虚拟主机,当请求无法匹配到任何一个虚拟主机上时,交给默认虚拟主机来处理。
1.5 Host
代表一个虚拟主机,每个虚拟主机和某个网络域名(Domain Name)相匹配。每个虚拟主机下都可以部署(deploy)一个或者多个Web应用程序(Web Application),每个Web应用程序对应于一个Context,有一个Context path。当虚拟主机获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理。匹配的方法是“最长匹配”,一个path=""的Context将成为该虚拟主机的默认Context。所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配。
在许多情况下,系统管理员希望将多个网络域名绑定到同一个虚拟主机,这就需要使用“主机别名”技术来实现。
1.6 Context
一个Context对应于一个Web应用程序,一个Web应用程序由一个或者多个Servlet组成。Context在创建的时候将根据配置文件$CATALINA_HOME/conf/web.xml和$WebApp /Web-INF/web.xml载入Servlet类。当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类。如果找到,则执行该类,获得请求的响应,并返回。
2 Tomcat Server处理一个http请求的过程
假设来自客户的请求为: http://localhost:8080/macy/index.jsp
1) 请求发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得。
2) Connector把该请求交给它所在Service的Engine来处理,并等待来自Engine的响应。
3) Engine获得请求localhost/macy/index.jsp,匹配它所拥有的所有虚拟主机Host。
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认虚拟主机)。
5) localhost Host获得请求/macy/index.jsp,匹配它所拥有的所有Context。
6) Host匹配到路径为/macy的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)。
7) path="/macy"的Context获得请求/index.jsp,在它的映射表中寻找对应的servlet。
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类。
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法。
10)Context把执行完了之后的HttpServletResponse对象返回给Host。
11)Host把HttpServletResponse对象返回给Engine。
12)Engine把HttpServletResponse对象返回给Connector。
13)Connector把HttpServletResponse对象返回给客户端浏览器。
如何正确编译servlet & 两个jre目录和三个lib目录
lib目录下放置着jar包。程序中的import语句找的就是这些文件!例如:import javax.servlet.RequestDispatcher;
问题在于,在cmd模式下编译,系统会提示:CheckAccount.java:5: 软件包 javax.servlet 不存在!
在安装jdk之后,仔细观察下安装路径下的文件夹,其中共计两处包含jre目录!共有三处lib目录!包含javax.servlet的jar包就应该被安置在其中的某一处。首先在tomcat的安装目录下,找到servlet-api.jar(位于D:/Program Files/Apache Software Foundation/Tomcat 6.0/lib/servlet-api.jar)。这个包用winrar解压之后看到内部结构为:
javax/servlet/http
同import语句的结构一致!
我的硬盘里,lib文件夹的位置如下:
D:/Program Files/Java/jdk1.6.0_02/jre/lib
D:/Program Files/Java/jre1.6.0_02/lib
D:/Program Files/Java/jdk1.6.0_02/lib
分别为jdk下的lib;jre下的lib;jdk下的jre下的lib。
经过验证,把servlet-api.jar包拷贝进入jdk下的jre下的lib下的ext目录后,import语句顺利通过编译!即:C:/Program Files/Java/jdk1.5.0_08/jre/lib/ext相关的,其他从外部导入的jar包,都放在这个目录下。例如:在工程中导入mysql驱动jar包“mysql-connector-java-3.0.17-ga-bin.jar”,其本质是拷贝了该jar包到ext目录下。其他情况,再添加oracle驱动jar包也类似处理。
再来解释下,为什么会有两处jre目录?三个lib目录分别什么作用?
安装JDK后,Java目录下有jdk和jre两个文件夹,但jdk下还有一个jre文件夹,而且这个jre比前面那个jre在bin目录下多了个server文件夹!
普通用户装jre即可。开发人员需要安装jdk,其中包括jre。所以jdk目录下包括jre目录。两个jre大体相同,有细微的差别。
两套 jre ,是针对不同的工作职责!不同的 jre 负责各自范围的内容。
当用户只需要执行 java 的程序时,那么C:/Program Files/Java/jre1.5.0_08的 jre 就 ok !
当用户是 java 程序员,则需要 java 开发环境。编译时,系统就会优先去找C:/Program Files/Java/jdk1.5.0_08/bin下的“ java 、 javac ”这些命令所在目录或者他们的父目录的 jre 。即开发环境下运行的是 jdk 下的 jre 。
再说三个lib目录:
JDK下的lib包括java开发环境的jar包,是给JDK用的,例如JDK下有一些工具,可能要用该目录中的文件。例如,编译器等。
JRE下的lib只是运行java程序的jar包,是为JVM运行时候用的。包括所有的标准类库,和扩展类。
JDK下的JRE下的lib是开发环境中,运行时需要的jar包。最典型的就是导入的外部驱动jar包。因为编译时,系统找的是jdk下的jre。而不是最外层的jre。
-----------------------------------------
最后我在这里补充几点:
1. 在使用Eclipse的时候不需要指定的CLASSPATH,Eclipse会自己搜索.
2. 独立目录下的jre是通用jre,安装时是可选的(选择了,则会覆盖已有版本)。jdk目录下的jre则是必须的。如果你在eclipse里指定jdk的路径(jre的路径不用你指定,会自己去找的),那么用的就是这个jre。而java, web, start等,用的则是通用jre。