谨以此文送给所有正在使用TOMCAT或者打算使用的人们向TOMCAT的所有开发人员致敬!
一小猫TOMCAT其实很可爱
年底我换公司了同样也换了WEBAPPTOMCAT出现在我的面前(以前使用weblogic)我有点茫然免费的东西真的能用的好么?担心ING……(其实是在火星呆太久)出门一打听原来此猫出自名门-jakarta项目年度最具创新的java产品(Most Innovative Java Product)又有JAVA的老大SUN的力捧(官方推荐的servlet和jsp容器)以后就靠它吃饭了不说二话搞起来先
安装
TOMCAT最新版本是()
如果在WINDOWS下它可以自动找到你的JDK或者set JAVA_HOME=c:/jdk
在LINUX下需要先解压然后设置JAVA_HOME
export JAVA_HOME=/usr/local/jdk
RUN
设置完毕后就可以运行tomcat服务器了进入tomcat的bin目录WINDOWS下用startup启动tomcatlinux下用startupsh相应的关闭tomcat的命令为shutdown和shutdownsh
启动服务后在浏览器里输//localhost:/来测试一下
目录结构
Bin存放启动和关闭tomcat脚本
Conf包含不同的配置文件serverxml(Tomcat的主要配置文件)
Work存放jsp编译后产生的class文件
Webapp存放应用程序示例以后你要部署的应用程序也要放到此目录
Logs存放日志文件
Comm/server/shared这三个文件夹下的LIB文件夹放jar文件
配置serverxml文件
没有什么好说的看TOMCAT的文档比较有用这里提供一些主要的东西吧
元素名
属性
解释
server
port
指定一个端口这个端口负责监听关闭tomcat的请求
shutdown
指定向端口发送的命令字符串
service
name
指定service的名字
Connector(表示客户端和service之间的连接)
port
指定服务器端要创建的端口号并在这个断口监听来自客户端的请求
minProcessors
服务器启动时创建的处理请求的线程数
maxProcessors
最大可以创建的处理请求的线程数
enableLookups
如果为true则可以通过调用requestgetRemoteHost()进行DNS查询来得到远程客户端的实际主机名若为false则不进行DNS查询而是返回其ip地址
redirectPort
指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号
acceptCount
指定当所有可以使用的处理请求的线程数都被使用时可以放到处理队列中的请求数超过这个数的请求将不予处理
connectionTimeout
指定超时的时间数(以毫秒为单位)
Engine(表示指定service中的请求处理机接收和处理来自Connector的请求)
defaultHost
指定缺省的处理请求的主机名它至少与其中的一个host元素的name属性值是一样的
Context(表示一个web应用程序通常为WAR文件关于WAR的具体信息见servlet规范)
docBase
应用程序的路径或者是WAR文件存放的路径
path
表示此web应用程序的url的前缀这样请求的//localhost:/path/****
reloadable
这个属性非常重要如果为true则tomcat会自动检测应用程序的/WEBINF/lib 和/WEBINF/classes目录的变化自动装载新的应用程序我们可以在不重起tomcat的情况下改变应用程序
host(表示一个虚拟主机)
name
指定主机名
appBase
应用程序基本目录即存放应用程序的目录
unpackWARs
如果为true则tomcat会自动将WAR文件解压否则不解压直接从WAR文件中运行应用程序
Logger(表示日志调试和错误信息)
className
指定logger使用的类名此类必须实现orgapachecatalinaLogger 接口
prefix
指定log文件的前缀
suffix
指定log文件的后缀
timestamp
如果为true则log文件名中要加入时间如下例:localhost_logtxt
Realm(表示存放用户名密码及role的数据库)
className
指定Realm使用的类名此类必须实现orgapachecatalinaRealm接口
Valve(功能与Logger差不多其prefix和suffix属性解释和Logger 中的一样)
className
指定Valve使用的类名如用orgapachecatalinavalvesAccessLogValve类可以记录应用程序的访问信息
directory
指定log文件存放的位置
pattern
有两个值common方式记录远程主机名或ip地址用户名日期第一行请求的字符串HTTP响应代码发送的字节数combined方式比common方式记录的值更多
管理
TOMCAT管理能力很强大进//localhost:/自己慢慢管吧实践出真知我喜欢这样搞
^_^一切尽在掌//localhost:/manager/html
一让数据库连接池转起来
作为一个JEE程序员大家手上可能会有现成的JDBC 数据库连接池其实这没有太大的必要因为象weblogic……企业级WEBAPP都有自己的连接池大家不要费力直接使用吧效率也很不错再也不用羡慕NET的ADO了(以前作MS从来不担心数据连接ADO确实用起来很爽)如果想实现一个 JDBC connection pool 的注意事项有
有一个简单的函数从连接池中得到一个 Connection
close 函数必须将 connection 放回 数据库连接池
当数据库连接池中没有空闲的 connection 数据库连接池必须能够自动增加 connection 个数
当数据库连接池中的 connection 个数在某一个特别的时间变得很大但是以后很长时间只用其中一小部分应该可以自动将多余的 connection 关闭掉
如果可能应该提供debug 信息报告没有关闭的 new Connection
网上有各种各样的连接池代码抄过来改改吧嘿嘿~
这里介绍如何配置TOMCAT的连接池以SQLSERVER为例
步骤安装SQLSERVER的JDBC驱动
SQLSERVER的JDBC驱动其实就是三个JAR文件msbasejar/mssqlserverjar/msutiljar将这三个文件拷贝到你的/tomcat_home/common/lib目录下去就可以了
步骤修改serverxml文件
具体代码如下
<Context path=test docBase=F:\yourroot debug= reloadable=true crossContext=true>
<Logger className=orgapachecatalinaloggerFileLogger prefix=localhost_DBTest_log suffix=txt timestamp=true/>
<Resource name=jdbc/SqlServerDB auth=Container type=javaxsqlDataSource/>
<ResourceParams name=jdbc/SqlServerDB>
<parameter>
<name>factory</name>
<value>monsdbcpBasicDataSourceFactory</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 for no limit>
<parameter>
<name>maxActive</name>
<value></value>
</parameter>
<! Maximum number of idle dB connections to retain in pool Set to for no limit>
<parameter>
<name>maxIdle</name>
<value></value>
</parameter>
<! Maximum time to wait for a dB connection to become available in ms in this example seconds An Exception is thrown if this timeout is exceeded Set to to wait indefinitely >
<parameter>
<name>maxWait</name>
<value></value>
</parameter>
<! msSQL dB username and password for dB connections >
<parameter>
<name>username</name>
<value>sa</value>
</parameter>
<parameter>
<name>password</name>
<value>sa</value>
</parameter>
<! Class name for SQLServer JDBC driver >
<parameter>
<name>driverClassName</name>
<value>commicrosoftjdbcsqlserverSQLServerDriver</value>
</parameter>
<! The JDBC connection url for connecting to your MS SQL Server dBThe autoReconnect=true argument to the url makes sure that the mmSql Server JDBC Driver will automatically reconnect if mysqld closed the connection mysqld by default closes idle connections after hours>
<parameter>
<name>url</name>
<value>jdbc:microsoft:sqlserver://:;databaseName=yourdb</value>
<!must use & not use & >
</parameter>
</ResourceParams>
</Context>
步骤三程序调用
package dbmanage;
import javasqlCallableStatement;
import javasqlConnection;
import javasqlDate;
import javasqlPreparedStatement;
import javasqlResultSet;
import javasqlSQLException;
import javasqlStatement;
import javautilEnumeration;
import javautilHashtable;
import javautilVector;
import javaxnamingContext;
import javaxnamingInitialContext;
import javaxsqlDataSource;
import utilsmartDateFormat;
public class dbManager {
/************************************
* @param static private boolean VERBOSE ;
* @param Statement theStatement;
* @param PreparedStatement thePstmt;
* @param Connection theConnection;
************************************/
final static private boolean VERBOSE = true; //打印控制台控制
//static Logger logger = LoggergetLogger(dbManagerclassgetName());
private Context initCtx = null;
private Context ctx = null;
private DataSource ds = null;
private long timeout = ;
private Statement theStatement = null;
private PreparedStatement thePstmt = null;
/************************************
* 初试化initCtx
* 取得数据源对象
************************************/
public
dbManager() {
try {
initCtx = new InitialContext();
//init contextread config webxml
if (initCtx == null) {
throw new Exception(Initial Failed!);
}
ctx = (Context) initCtxlookup(java:comp/env);
//find jdbc/SqlServerDB object this configruation in the SERVERXML of Tomcat
if (ctx != null) {
ds = (DataSource) ctxlookup(jdbc/SqlServerDB);
}
if (ds == null) {
throw new Exception(Look up DataSource Failed!);
}
}
catch (Exception e) {
log(e Cant get the Context!);
}
}
/************************************
* get Connection
* @return Connection
************************************/
public synchronized
Connection getConnection() {
//get connection and set to delay time
long startTime = new javautilDate()getTime();
Connection con = null;
while (con == null) {
con = newConnection();
if (con != null) {
//log(Create New Connection!);
break;
}
try {
log(连接超时重新连接等待 + timeout + ms);
wait(timeout);
}
catch (InterruptedException e) {
log(e 连接超时!);
}
if ( (new javautilDate()getTime() startTime) >= timeout) {
log(Connection timeout!);
break;
}
}
return con;
}
private
Connection newConnection() {
Connection con = null;
try {
con = dsgetConnection();
if (con == null) {
throw new Exception(Create Connection Failed!);
}
}
catch (Exception e) {
log(Create Connection Failed!);
Systemoutprintln(egetMessage());
}
return con;
}
/************************************
* release the connection
* @param conn Connection
* @param stmt Statement
* @param pstmt PreparedStatement
************************************/
public synchronized
void freeConnection(Connection conn
Statement stmt
PreparedStatement pstmt) {
try {
//close Statement
if (stmt != null) {
stmtclose();
stmt = null;
//log(Close Statement);
}
//close PreparedStatement
if (pstmt != null) {
pstmtclose();
pstmt = null;
//log(Close PreparedStatement);
}
}
catch (Exception e) {
Systemoutprintln(egetMessage());
}
try {
//close Connection
if (conn != null) {
connclose();
conn = null;
//log(Close Connection);
}
}
catch (SQLException e) {
log(e 释放资源出错!);
}
}
/************************************
* write log file
* @param s String
************************************/
private
void log(String s) {
if (VERBOSE) {
Systemoutprintln(new javautilDate() + : + s);
//(new javautilDate()+s);
}
}
/************************************
* write log file
* @param ex Object
************************************/
private
void logerr(Object ex) {
if (VERBOSE) {
//Systemoutprintln(new javautilDate()+:+s);
//loggererror(ex);
}
}
/************************************
* write log file
* @param e Throwable
* @param msg String
************************************/
private
void log(Throwable e String msg) {
Systemoutprintln(new javautilDate() + : + msg);
//(new javautilDate() + : + msg e);
}
……
}
OK你现在可以方便的使用连接池了想要一个得一个记得要释放哦连接池的数量总是有限的
二中文问题照样很简单
每个国家(或区域)都规定了计算机信息交换用的字符编码集如美国的扩展 ASCII码 中国的 GB日本的 JIS 等作为该国家/区域内信息处理的基础有着统一编码的重要作用字符编码集按长度分为 SBCS(单字节字符集)DBCS(双字节字符集)两大类早期的软件(尤其是操作系统)为了解决本地字符信息的计算机处理出现了各种本地化版本(LN)为了区分引进了 LANG Codepage 等概念但是由于各个本地字符集代码范围重叠相互间信息交换困难软件各个本地化版本独立维护成本较高因此有必要将本地化工作中的共性抽取出来作一致处理将特别的本地化处理内容降低到最少这也就是所谓的国际化(IN)各种语言信息被进一步规范为 Locale 信息处理的底层字符集变成了几乎包含了所有字形的 Unicode
现在大部分具有国际化特征的软件核心字符处理都是以 Unicode 为基础的在软件运行时根据当时的 Locale/Lang/Codepage 设置确定相应的本地字符编码设置并依此处理本地字符在处理过程中需要实现 Unicode 和本地字符集的相互转换甚或以 Unicode 为中间的两个不同本地字符集的相互转换这种方式在网络环境下被进一步延伸任何网络两端的字符信息也需要根据字符集的设置转换成可接受的内容
Java 语言内部是用 Unicode 表示字符的遵守 Unicode VJava 程序无论是从/往文件系统以字符流读/写文件还是往 URL 连接写 HTML 信息或从 URL 连接读取参数值都会有字符编码的转换这样做虽然增加了编程的复杂度容易引起混淆但却是符合国际化的思想的从理论上来说这些根据字符集设置而进行的字符转换不应该产生太多问题而事实是由于应用程序的实际运行环境不同Unicode 和各个本地字符集的补充完善以及系统或应用程序实现的不规范转码时出现的问题时时困扰着程序员和用户
其实解决 JAVA 程序中的汉字编码问题的方法往往很简单但理解其背后的原因定位问题还需要了解现有的汉字编码和编码转换相信这样的东西大家都见过了
new String(requestgetParameter(test)getBytes(iso)GBK)
但这样的代码相信不是一个解决的办法这样会增加程序的复杂度写数据库提交表单URL中传中文参数到处都是中文问题!作为一个连走路都要算计最短距离的懒人当然不愿天天叨念着new String(requestgetParameter(test)getBytes(iso)GBK)然汉战战兢兢的处理各种字符转换的问题我跋山涉水翻山越岭终于找到了完美的解决方式在TOMCAT中只需要简单的配置引入个文件就可以轻松搞定
前提条件每个页面使用
<%@ page contentType=text/html; charset=GBK language=java import=javasql* errorPage= %>
<meta httpequiv=ContentType content=text/html; charset=GBK>
地球人都知道的东西
步骤添加过滤器
在TOMCAT中找到这个文件RequestDumperFilterjavaSetCharacterEncodingFilterjava他们位于D:\Tomcat\webapps\jspexamples\WEBINF\classes\filters加到你的工程文件里去编译他们
步骤配置WEBXML
在webxml里加入这一段
……
<filter>
<filtername>Set Character Encoding</filtername>
<filterclass>filtersSetCharacterEncodingFilter</filterclass>
<initparam>
<paramname>encoding</paramname>
<paramvalue>GBK</paramvalue>
</initparam>
</filter>
<filtermapping>
<filtername>Set Character Encoding</filtername>
<urlpattern>/*</urlpattern>
</filtermapping>
……
看到没有?这样你就不用写那些麻烦的转换代码了当然这样还不足以解决问题
步骤修改serverxml
在serverxml修改个地方
<Connector port=
maxThreads= minSpareThreads= maxSpareThreads=
enableLookups=false redirectPort= acceptCount=
debug= connectionTimeout=
disableUploadTimeout=true URIEncoding=GBK/>
<Connector className=yotetomcatCoyoteConnector
port= minProcessors= maxProcessors=
enableLookups=true redirectPort=
acceptCount= debug= connectionTimeout=
useURIValidationHack=false protocol=AJP/
protocolHandlerClassName=orgapachejkserverJkCoyoteHandler
URIEncoding=GBK/>
OK搞定!
三APACHE和TOMCAT他们俩关系非同一般
Apache和tomcat都是很优秀的软件更可贵的是它们是免费的其实他们个都是jakarta项目的重要组成部分按辈分来讲TOMCAT是APACHE的儿子APACHE的专长是解析静态文件CGIPHP……图片……儿子当然不能抢了老爹的饭碗所以TOMCAT只有在JEE这个上面发愤图强其实TOMCAT并非不能干他老爹的活只是稳定性差点而已(偶没有明显的感觉可能是商业炒作吧)现在大家明白为什么把他们个扯一起了吧上阵还靠父子兵呢~
把个家伙整一起有大致有种方法一种是利用mod_jkso一种是利用mod_jk__dll这个东东叫联接器(TOMCAT就是通过这家伙与apache勾搭上的)
利用mod_jk__dll在WINDOWS下整合
步骤准备材料
apache
_winxno_sslmsi
tomcat
/v/bin/jakartatomcatexe
JDK(这个不用说了吧^_^)
mod_jk__dll(关键是这个东东啊找了我N久)据说在下面连接可以下到最后在我同事那找到的
connectors/jk/binaries/win/mod_jk__dll
安装apache\ tomcat\JDK
步骤安装后设置环境变量
设置我的电脑\属性\高级\环境变量\新建系统变量变量名JAVA_HOME 变量值C:\JBuilderX\jdk (指向JDK的实际安装路径)TOMCAT_HMOM 变量值Tomcatlasspath 编辑变量值中加上……;%JAVA_HOME%\bin;%JAVA_HOME%\lib;%TOMCAT_HOME%\bin;;
测试一下访////localhost:默认安装是不会有什么错误的^_^
把连接器mod_jk__dllCOPY到D:\Apache\modules\下
步骤apache配置
在d:\Apache\conf下找到后添加indexjsp查找listen用于本机测试时Listen :我的是这样设置的Listen *:
查找AddDefaultCharset设置为AddDefaultCharset off这样APACHE将以你页面定义的字符集解析页面
在最后添加如下代码
<VirtualHost *:> #localhost为本机你可用本机ip
ServerAdmin #你的mail地址
DocumentRoot F:/uutang/uutang #你的项目组根目录
ServerName dark #你的服务名若你的机器有域名设为域名
ErrorLog logs/ErrorLogtxt #错误日志
CustomLog logs/CustomLogtxt common #访问日志
JkMount /servlet/* ajp #让Apache支持对servlet传送用以Tomcat解析
JkMount /*jsp ajp #让Apache支持对jsp传送用以Tomcat解析
JkMount /*do ajp #让Apache支持对struts的action传送用以Tomcat解析
</VirtualHost>
LoadModule jk_module modules/mod_jk__dll
JkWorkersFile D:/Tomcat/conf/workersproperties
JkLogFile D:/Tomcat/logs/mod_jklog
JkLogLevel info
步骤tomcat配置
在d:\Tomcat\conf下新建一个workersproperties文件 内容如下:
workerstomcat_home=d:\Tomcat #让mod_jk模块知道Tomcat
workersjava_home=d:\jdk #让mod_jk模块知道jsdk
ps=\
workerlist=ajp #模块版本现有ajp了不要修改
workerajpport= #工作端口若没占用则不用修改
workerajphost=localhost #主机若上面的Apache主机不为localhost作相应修改
workerajptype=ajp #类型
workerajplbfactor= #代理数不用修改
修改TOMCAT的serverxml文件
<! Define a Coyote/JK AJP Connector on port >
<Connector className=yotetomcatCoyoteConnector
port= minProcessors= maxProcessors=
enableLookups=true redirectPort=
acceptCount= debug= connectionTimeout=
useURIValidationHack=false protocol=AJP/
protocolHandlerClassName=orgapachejkserverJkCoyoteHandler
URIEncoding=GBK/>
让TOMCAT知道ajp协议apache和tomcat俩父子间靠这个协议沟通
测试一下访////localhost:看到相同的页面没有?细心点其实很简单看看E文的帮助搞定不成问题
利用mod_jkso(也叫JK)整合
jk是一个jakartatomcatconnectorsjkwinapachezip文件主要用的是其中的mod_jkso其实利用mod_jkso整合和利用mod_jk__dll整合大同小异只是换了个联接器而已现在一步一步整起来~
步骤没有多说的安装好TOMCAT和APACHE
下载jakartatomcatconnectorsjkwinapachezip解压将mod_jk放到apache的安装文件夹下的modules文件夹中
步骤apache配置
在/conf中加入一个workproperties文件其内容如下
<!这个文件的作用不是很清楚总之路径设置正确就行了我的apache装在D:/Apache根据情况自己修改>
[shm]
file=D:/ /Apache/logs/shmfile
size=
<!这个socket channel是必须的port和host对应于tomcat端的设置>
#The socket channel
[channelsocket:localhost:]
port=
host=localhost
<!worker必须的>
#define the worker
[ajp:localhost:]
channel=channelsocket:localhost:
<!url mapping我的主要是jsp和struts的doservlet的话设置成[uri:/xxx/*]之类的>
#uri mapping
[uri:/*] #和第一种方式一样吧^_^
[uri:/*jsp]
[uri:/*do]
worker=ajp:localhost:
在中在LoadModule那里加入这句
LoadModule jk_module modules/mod_jkso
在最后加入这句
JkSet configfile conf/workproperties
这是告诉apache去哪里找jk的配置的根据具体情况修改
还要修改一下DirectoryIndexDirectoryIndex l lvar indexjsp查找listen用于本机测试时Listen :我的是这样设置的Listen *:
当然还有我们的虚拟目录
<VirtualHost *:>
ServerAdmin
DocumentRoot F:/uutang/uutang
ServerName dark
ErrorLog logs/ErrorLogtxt
CustomLog logs/CustomLogtxt common
#JkMount /servlet/* ajp
#JkMount /*jsp ajp
#JkMount /*do ajp
</VirtualHost>
步骤tomcat配置
Tomcat的端口设置为
在/conf文件夹加入jkproperties文件其内容如下
# Set the desired handler list
handlerlist=aprrequestchannelSocket
#
# Override the default port for the socketChannel
channelSocketport=
TOMCAT自己已经生成了这个文件找到相关的地方把注视去掉改一下就成
注意用这种方式整合最好是自己编译mod_jkso文件特别是在unix/linux下我没有环境制作mod_webappso没有自己作过具体方法自己去找吧