Tomcat 4.1配置和使用

来源:互联网 发布:淘宝千人千面怎么设置 编辑:程序博客网 时间:2024/05/01 18:58

正文:

Tomcat是Apache Jakarta项目中的一个Servlet服务器,已经被程序员广泛用来开发Servlet和Jsp项目。该服务器占用资源小,扩展性好,支持多种功能(如负载平衡、邮件服务等等,这得益于Jakarta项目的开放性);更因为它是一个完全免费和完全开放的服务器,所以有成千上万的程序员在努力完善和添加已有的功能,可以在互联网上搜索到大量的关于tomcat的资源和解决方案。

在http://jakarta.apache.org 上可以下载到Tomcat,目前最新版本5.0还没有正式发布。所以现在可用的是4.1版本。

Tomcat 4.1可自动安装(需要下载自动安装版本,也有zip打包的版本和源代码),但你事先要安装好JDK。可以选择jdk1.3(1.2.x或者1.3.x)或者1.4来安装。注意下载相应Jdk版本的Tomcat。在安装的时候,如果选择安装服务,安装程序可以把tomcat自动添加到Win NT或者Win 2000的服务中,服务名称是"Apache Tomcat 4.1"。你可以在控制面板的服务中找到它,通过服务的图形界面启动/停止;或者使用命令:net start "Apache Tomcat 4.1" 和 net stop "Apache Tomcat 4.1"来启停它。如果需要移除服务,在%TOMCAT_HOME%(表示Tomcat的安装目录,下同)的bin目录下,找到tomcat.exe ,在命令行打入tomcat -remove "Apache Tomcat 4.1",就可以了。如果你在自动安装的时候没有选择安装服务,可以以后通过在命令行打入 tomcat -install "Apache Tomcat 4.1"来安装。在安装的过程中可能会出现控制台不关闭的现象,这时把控制焦点放在控制台上,按下回车键,即可顺利继续安装。

Tomcat 4.1内部实现了Servlet 2.3和Jsp l.2引擎。如果需要使用数据库连接池,一定要使用Tomcat4.1以上版本,因为Tomcat 4.1才开始内置对数据库连接池的支持。关于Tomcat内置的连接池的配置,见如下步骤:

1.寻找第三方的数据库java的驱动(如db2的驱动是db2java.zip文件),并且把它拷贝到Tomcat的库文件目录下。在这里是%TOMCAT_HOME%的common/lib子目录下。注意,一定要把文件变成.jar文件,再拷过来。否则可能出现认不出驱动的问题。

2.配置%TOMCAT_HOME%的conf下的server.xml文件。在Host分支下,删除不必要的Context(如最初安装可能装了Example等,注释掉相关描述)。加入自己的Context,以下是一个附有注释说明的例子:

<!-- 自己的Context,名称叫做ppc -->

<Context path="/ppc" docBase="ppc" debug="5" reloadable="true" crossContext="true">

<!-- 日志,在%TOMCAT_HOME%的logs下生成localhost_ppc_log.txt日志文件 -->

<Logger className="org.apache.catalina.logger.FileLogger"

prefix="localhost_ppc_log." suffix=".txt"

timestamp="true"/>

<!-- 数据源名称,可以通过java:/comp/env/jdbc/emr调用(连接池) -->

<Resource name="jdbc/emr"

auth="Container"

type="javax.sql.DataSource"/>

<!-- 数据源参数表 -->

<ResourceParams name="jdbc/emr">

<!-- 数据源工厂,通过它得到DataSource -->

<parameter>

<name>factory</name>

<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

</parameter>

<!-- Maximum number of dB connections in pool. Make sure you

configure your mysqld max_connections large enough to handle

all of your db connections. Set to 0 for no limit.

最大连接数

-->

<parameter>

<name>maxActive</name>

<value>100</value>

</parameter>

<!-- Maximum number of idle dB connections to retain in pool.

Set to 0 for no limit.

最大空闲连接数

-->

<parameter>

<name>maxIdle</name>

<value>30</value>

</parameter>

<!-- Maximum time to wait for a dB connection to become available

in ms, in this example 10 seconds. An Exception is thrown if

this timeout is exceeded. Set to -1 to wait indefinitely.

最长等待连接时间,如果设置成-1表示不确定

-->

<parameter>

<name>maxWait</name>

<value>5000</value>

</parameter>

<!--

db2 dB username and password for dB connections

这里配置的是db2的连接

-->

<!-- 用户名 -->

<parameter>

<name>username</name>

<value>db2admin</value>

</parameter>

<!-- 密码 -->

<parameter>

<name>password</name>

<value>db2admin</value>

</parameter>

<!-- DB2 驱动的类名称 -->

<parameter>

<name>driverClassName</name>

<value>COM.ibm.db2.jdbc.app.DB2Driver</value>

</parameter>

<!--

jdbc连接的url名称

在这里已经安装了db2的控制终端

-->

<parameter>
<name>url</name>

<value>jdbc:db2:emr</value>

</parameter>

</ResourceParams>

</Context>

3.在相应用到该连接池的Web-app(部署好的web应用,一般在%TOMCAT_HOME%的webapps目录下,也可以通过编辑server.xml来改变,下同)的WEB-INF下面修改web.xm

l,在web-app分支内加入数据源,见下面的例子:

<resource-ref>

<!-- 数据源描述,可随意取有意义的名称 -->

<description>emr db2 dabasource</description>

<res-ref-name>jdbc/emr</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource-ref>

这样子连接池就完全配置好了。在程序中,可以如同标准j2ee的写法那样子使用,见下面的例子:

Context ctx = new InitialContext();//创建上下文实例

DataSource ds =

(DataSource)ctx.lookup(

"java:comp/env/jdbc/emr");//得到数据源(连接池)

if (ds != null)

Connection conn = ds.getConnection();//从连接池中得到连接

4.调试和测试

一般在配置中总会出现这样那样的问题,可以写一段简单的调试代码来发现问题的所在,以下是一段代码片断,可以参考下面代码片断的顺序逐步发现问题:

try{Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");}//1.是否能够找到数据库驱动

catch(ClassNotFoundException cnfe){out.println(cnfe.toString());}//不能找到,打印错误

javax.naming.Context ctx =new javax.naming.InitialContext();

javax.naming.Context envContext = (javax.naming.Context)ctx.lookup("java:/comp/env");//2.是否能够找到环境的命名空间

out.println(envContext);//找不到,打印错误

org.apache.commons.dbcp.BasicDataSource ds=(org.apache.commons.dbcp.BasicDataSource)envContext.lookup("jdbc/emr");//3.是否能够取得数据源。这里一定用BasicDataSource接收以获得比DataSource接口更具体的信息,便于错误查找

if(ds==null)out.println(ds);//找不到,打印错误

else{

//4.看数据源的具体信息有没有从server.xml中读取出来

//还可以看的项有usrname、url等等

out.println(ds.getValidationQuery());

out.println(ds.getMaxActive());

out.println(ds.getPassword());

out.println(ds.getDriverClassName());

}

一般通过以上4个步骤可以确定错误出在哪里了。

以下部分主要讲Tomcat的编码问题。

Tomcat的编码问题,一般指的是jsp或者servlet的编码出现乱码,解决见如下步骤:

1. Tomcat编码问题出现的地方:

Tomcat的编码问题比较烦,一般出在编译阶段、打印阶段或者request接收阶段。

2. 编译阶段编码问题的解决:

在编译阶段出现编码问题,可以强制指定编译器所用的编码。

在%TOMCAT_HOME%的conf下,编辑web.xml,找到

<servlet>

<servlet-name>jsp</servlet-name>

<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>

<load-on-startup>3</load-on-startup>

</servlet>

这段描述,在servlet下面加入子标签

<init-param>

<param-name>javaEncoding</param-name>

<param-value>iso-8859-1</param-value>

</init-param>

其中iso-8859-1可以换成你需要的编码,如gb2312;如果不指定,就是utf-8。注意编译器不能认出gbk,所以不要用gbk作为编码。

3. 页面打印到屏幕阶段出现编码问题的解决

编码如果在jsp页面打印时出现乱码,可以考虑设置页面的编码。只要在jsp的最开始处,加入

<%@page contentType="text/ht

ml;charset=gb2312" %>标签就可以了(简体中文,其他编码自己修改charset后的值)。

4. request接收阶段出现编码问题的解决

如果在request接收另外一个页面或者页面本身传递来的变量时出现乱码,可以设置request的编码来解决,只要在servlet程序或者jsp页面最开始加入

request.setCharacterEncoding("gb2312");//gb2312为简体中文,其他编码作相应的修改

这个片断即可。

但是,这样子写有破坏程序的移植性的嫌疑。因为如果另外一个serlet引擎恰恰因为加入了这段语句而画蛇添足,出现乱码,就不好了。所以,可以有以下2种方法解决这个问题。

4.1 写include文件,把编码的两段话加入到被包含的jsp文件中。如果真的因为手工编码的原因出现了乱码,可以修改被包含的jsp文件,解决所有的编码问题。

如:<jsp:include page="/codeSetting.jsp" />

4.2 写servlet过滤器。通过过滤器来解决request的编码的设置。这个方法不需要改动原来的代码,比较好。现成的写好的过滤器代码贴在下面,只要把它编译一下就可以用了:

package filters;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.UnavailableException;

/**

* Example filter that sets the character encoding to be used in parsing the

* incoming request, either unconditionally or only if the client did not

* specify a character encoding.

* 如果原来没有设置request的编码,就设置;否则保持不变

*/

public class SetCharacterEncodingFilter implements Filter {

protected String encoding = null;

protected FilterConfig filterConfig = null;

protected boolean ignore = true;

/**

* Take this filter out of service.

*/

public void destroy() {

this.encoding = null;

this.filterConfig = null;

}

/**

* Select and set (if specified) the character encoding to be used to

* interpret request parameters for this request.

*/

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain)

throws IOException, ServletException {

// Conditionally select and set the character encoding to be used

if (ignore || (request.getCharacterEncoding() == null)) {

String encoding = selectEncoding(request);

if (encoding != null)

request.setCharacterEncoding(encoding);//设置request编码的地方

}

// Pass control on to the next filter

// 传递控制到下一个过滤器

chain.doFilter(request, response);

}

/**

* Place this filter into service.

* 从web-app的web.xml文件中读取初始参数的值

*/

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

this.encoding = filterConfig.getInitParameter("encoding");

String value = filterConfig.getInitParameter("ignore");

if (value == null)

this.ignore = true;

else if (value.equalsIgnoreCase("true"))

this.ignore = true;

else if (value.equalsIgnoreCase("yes"))

this.ignore = true;

else

this.ignore = false;

}

/**

* Select an appropriate character encoding to be used, based on the

* characteristics of the current request and/or filter initialization

* parameters. If no character encoding should be set, return

* <code>null</code>.

* 选择request原来的编码

*/

protected String selectEncoding(ServletRequest request) {

return (this.encoding);

}

}

编译好以后,把SetCharacterEncodingFilter.class加入到相应的web-app的WEB-INF/classes/filters目录下,并且在web.xml的web-app中添加如下语句,配置这段作为filter的servlet:

<filter>

<filter-name>Set Character Encoding</filter-name>

<filter-class>filters.SetCharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<!-- gb2312可以换成需要的编码 -->

<param-value>gb2312</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>Set Character Encoding</filter-name>

<!-- 所有的页面包括servlet,jsp都使用这段过滤器,可以自行指定filter的作用范围 -->

<url-pattern>/*</url-pattern>

</filter-mapping>

5. 编码问题的其他解决方法:全球化解决方案。

以上的配置完成的是本地化的问题。但是我们可以在所有的过程中都采用相同的编码,如范围足够大的iso-8859-1。因为java是unicode的设计,所以只要代码传递中不出现信息的失真,就可以把编码问题推向最终显示时用户的浏览器的设置,也就实现了全球化。关键是不要出现编码的高位截取。一般,页面上出现???符号时代码出现了失真。

Tomcat的其他问题:

Tomcat 4.1可能不如resin 2.1稳定,其中有一些古怪的bug。但是比resin更灵活,因为它是jakarta项目中的一部分,组件很多,扩充性更强。所以也还是比较适合开发和研究的。

以下是这样一个奇怪的bug:

在tomcat作为jsp服务器的时候,jsp语句中这样写

<tr bgcolor="<%if(info.getCy()!=null && info.getCy().trim().equals("是"))out.print("#dddddd");else out.print("#ffdddd");//是和否用不同的颜色表示%>">

按道理,"<%"和"%>"中的语句是动态语句,而他们外面的是静态语句。注释只应该对内有效。在resin中的确如此,很正常。但是在tomcat4.1下,外面的">"居然也给注释掉了。证明tomcat的语法分析部分还是有点问题的。希望5.0正式发布的时候看到它已经给解决掉了。