用java写的webservice,建立数据库连接的时候,因为webservice接口要供很多用户使用,这时如果把数据库连接语句写在用户调用的我方的方法里面,在方法里面用完再关闭,也可以。但是用tomcat连接池,一开始就申请25个连接放着,最多50个(这个25和50都可以配置),省了很多创建及关闭连接的时间,抗压能力会好点。更科学的用法,是用Tomcat连接池。
配置方法:
1.在tomcat的server.xml文件中加入如下代码(红色部分为要添加的,紫色字体为需要根据实际情况修改的。假如程序中既要连接oracle,又要连接sqlserver2005):
.....................
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="U4ser database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource name="DataSourceSql" auth="Container"
type="javax.sql.DataSource"
username="sa" password="pwd"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://127.0.0.1:8080;databasename=dbname" logAbandoned="true" maxActive="50" maxIdle="25" maxWait="20000"/>
<Resource name="DataSourceOracle" auth="Container"
type="javax.sql.DataSource"
username="username" password="pwd"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:8080:dbname" logAbandoned="true" maxActive="50" maxIdle="25" maxWait="20000"/>
</GlobalNamingResources>
........................
<Connector port="8899" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8483" URIEncoding="utf-8" />
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/De_WS" docBase="E:\De_WS\WebRoot" reloadable="true" debug="0">
<ResourceLink global="DataSourceSql" name="DataSourceSql" type="javax.sql.Datasource"/>
<ResourceLink global="DataSourceOracle" name="DataSourceOracle" type="javax.sql.Datasource"/>
</Context>
(说明:访问接口地址时,如果是启动本机tomcat,那么就是
String url ="http://localhost:8899/De_WS/services/ClientJK";
访问地址为什么是这个?这是上面绿色中配的路径。
上面<Host name 中,只有红色字体部分是要加的,其他都是配置文件中本来就存在的。
绿色字体中:
webapps对应tomcat目录下的webapps文件夹。如果不配下面的<Context path="/De_WS" docBase="E:\De_WS\WebRoot.. tomcat会到webapps目录中找。
<Context path="/De_WS" docBase="E:\De_WS\WebRoot" 中。path="/De_WS"是虚拟目录的路径,docBase="E:\De_WS\WebRoot"是虚拟目录的实际物理地址(该地址要配置到WEB-INF的紧上一级目录)。因为这里配置了path="/De_WS" ,所以访问的时候http://localhost:8899后面要加/De_WS。如果配置path="",那么访问接口时,只用访问http://localhost:8899加后面的/services/ClientJK就可以了。/services/这个名字,是在webservice里的web.xml文件里配置的。ClientJK是在deploy.wsdd文件里配置的。
所以,访问接口地址中是否要加/De_WS,取决于 <Context path="/De_WS"中path(虚拟目录)的配置。
maxActive="50" maxIdle="25" maxWait="20000"/ 意思分别是,连接池最大50个连接,启动tomcat就申请25个连接,不管这25个是否一开始就用,这样节约申请连接的时间。20000意思是当50个连接用完后,等待20S,如果有被释放的连接,就拿着用,没有,就tomcat报错。
2.java程序中,连接数据库的代码改成:
import java.sql.Connection;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ConnectionManager { //连接oracle类
private static Log logger = LogFactory.getLog(ConnectionManager.class); //此处是将打印打印到log日志文件,路径配置在log4j文件中
private Connection conn = null;
public static Connection getConnection() throws Exception {
DataSource ds = getDataSource();
return ds.getConnection();
}
public static DataSource getDataSource() throws Exception {
try {
javax.naming.Context ctx = new javax.naming.InitialContext();
Object obj = null;
obj = ctx.lookup("java:comp/env/DataSourceOracle"); //步骤1中tomcat配好后,这里只用写配置中的名字即可
DataSource ds = (javax.sql.DataSource) obj;
return ds;
} catch (NamingException ne) {
logger.error("Context fail to lookup JNDIDataSourceName!"
+ ne.getMessage());
throw ne;
}
}
// public static Connection getConnection() throws Exception { //通过读取配置文件连接数据库
// Properties p = new Properties();
// InputStream is= ConnectionManager.class.getResourceAsStream("/config/other/init.properties");
// p.load(is);
// Class.forName(p.getProperty("jdbc.driver"));
// return DriverManager.getConnection(p.getProperty("jdbc.url"), p
// .getProperty("jdbc.username"), p.getProperty("jdbc.password"));
// }
}
package com.tools;
import java.sql.Connection;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class BaseDao { //连接sqlserver2005数据库
// public Connection GetConn() throws Exception { //通过读取配置文件连接数据库
// Connection conn = null;
// Properties p = new Properties();
// InputStream is = ConnectionManager.class
// .getResourceAsStream("/config/other/init_sql2005.properties");
// p.load(is);
// Class.forName(p.getProperty("jdbc.driver"));
// conn = DriverManager.getConnection(p.getProperty("jdbc.url"), p
// .getProperty("jdbc.username"), p.getProperty("jdbc.password"));
// return conn;
// }
private static Log logger = LogFactory.getLog(ConnectionManager.class);
private Connection conn = null;
public static Connection GetConn() throws Exception {
DataSource ds = getDataSource();
return ds.getConnection();
}
public static DataSource getDataSource() throws Exception {
try {
javax.naming.Context ctx = new javax.naming.InitialContext();
Object obj = null;
obj = ctx.lookup("java:comp/env/DataSourceSql");
DataSource ds = (javax.sql.DataSource) obj;
return ds;
} catch (NamingException ne) {
logger.error("Context fail to lookup JNDIDataSourceName!"
+ ne.getMessage());
throw ne;
}
}
}
如果用读取配置文件连接数据库(即其中注释掉的方法,配置文件内容如下):
init.properties
#created by Apusic
#Thu Nov 10 14:48:52 CST 2011
gis.ip=..
paging.number.per=10
jdbc.password=pwd
sms.ip=...
jdbc.maxActive=50
jdbc.url=jdbc\:oracle\:thin\:@192.168.1.1\:1521\:dbname
valuelisthandlerclass=oracle
jdbc.maxWait=50000
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.username=username
pci.ip=...
3.程序中调用webservice代码:
public class TestClient {
public static void main(String[] args) {
String url ="http://192.168.1.1:8080/De_WS/services/ClientJK"; //ClientJK是接口名称,访问时,为什么要加/De_WS目录,在过程1中说明会有详细介绍
Service service = new Service();
Call call =null;
try {
call = (Call) service.createCall();
call.setTargetEndpointAddress(new URL(url));
call.setOperationName("sendMsg"); //sendMsg是接口提供的方法名
String myName = (String)call.invoke(new Object[]{"参数1", "参数2","参数3","参数4","参数5" });
System.out.println("myName:"+myName);
} catch (ServiceException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
4.题外话。log4j日志输出方法(要导包):
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
....
private Log logger = LogFactory.getLog(SendThread.class);
....
long startTime = System.currentTimeMillis(); // -------------------获取开始时间
long endTime = System.currentTimeMillis(); // ------------------------获取结束时间
logger.info("线程中事务耗时: " + (endTime - startTime) //输出到日志文件
+ "ms");
.....
try {
ps2.close();
ps2 = null;
} catch (SQLException e) {
logger.error(e.getMessage()); //输出到日志文件
}
log4j.properties配置文件:
log4j.rootLogger=info, A1,A2 //info是tomcat启动方式为info(II),还有debug(I),warn(III),error(IV)。A1是输出到终端,A2是输出到日志文件
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%5p (%F%M:%L) - %m%n
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=c:/logs/XXX/info.log //此处是配置日志文件路径。目录要自己事先建好,info.log文件不用建
log4j.appender.A2.DatePattern='('yyyy-MM-dd')'
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d [%p] %c -line:%L - %m%n
log4j.logger.org.apache.commons=off
log4j.logger.org.apache.struts=off
log4j.logger.org.springframework=off
log4j.logger.com.ysoft=off