??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区二区三区影院,在线观看免费视频综合,亚洲国产欧美日本视频http://www.aygfsteel.com/aiyoyoyo/category/7534.htmlq是我的成长Q这是我的天圎ͼ学习JAVAQ只因快乐?/description>zh-cnThu, 01 Mar 2007 18:24:59 GMTThu, 01 Mar 2007 18:24:59 GMT60Java Servletq接池的Ҏhttp://www.aygfsteel.com/aiyoyoyo/articles/31225.htmlaiyoyoyoaiyoyoyoFri, 17 Feb 2006 08:43:00 GMThttp://www.aygfsteel.com/aiyoyoyo/articles/31225.htmlhttp://www.aygfsteel.com/aiyoyoyo/comments/31225.htmlhttp://www.aygfsteel.com/aiyoyoyo/articles/31225.html#Feedback0http://www.aygfsteel.com/aiyoyoyo/comments/commentRss/31225.htmlhttp://www.aygfsteel.com/aiyoyoyo/services/trackbacks/31225.html

一、实现连接池的意?nbsp;

动态Web站点往往用数据库存储的信息生成Web面Q每一个页面请求导致一ơ数据库讉K。连接数据库不仅要开销一定的通讯和内存资源,q必d成用户验证、安全上下文配置q类dQ因而往往成ؓ最时的操作。当Ӟ实际的连接时间开销千变万化Q但1?Ugqƈ非不常见。如果某个基于数据库的Web应用只需建立一ơ初始连接,不同面h能够׃n同一q接Q就能获得显著的性能改善?nbsp;
Servlet是一个JavacRServlet引擎Q它可能是Web服务软g的一部分Q也可能是一个独立的附加模块Q在pȝ启动或ServletW一ơ被h时将该类装入Java虚拟机ƈ创徏它的一个实例。不同用戯求由同一Servlet实例的多个独立线E处理。那些要求在不同h之间持箋有效的数据既可以用Servlet的实例变量来保存Q也可以保存在独立的辅助对象中?nbsp;
用JDBC讉K数据库首先要创徏与数据库之间的连接,获得一个连接对象(ConnectionQ,p接对象提供执行SQL语句的方法。本文介l的数据库连接池包括一个管理类DBConnectionManagerQ负责提供与多个q接池对象(DBConnectionPoolc)之间的接口。每一个连接池对象理一lJDBCq接对象Q每一个连接对象可以被L数量的Servlet׃n?nbsp;
cDBConnectionPool提供以下功能Q?nbsp;

1) 从连接池获取Q或创徏Q可用连接?nbsp;
2) 把连接返回给q接池?nbsp;
3) 在系l关闭时释放所有资源,关闭所有连接?nbsp;

此外Q?nbsp;DBConnectionPoolc还能够处理无效q接Q原来登Cؓ可用的连接,׃某种原因不再可用Q如时Q通讯问题Q,q能够限制连接池中的q接L不超q某个预定倹{?nbsp;
理cDBConnectionManager用于理多个q接池对象,它提供以下功能: 

1) 装蝲和注册JDBC驱动E序?nbsp;
2) Ҏ在属性文件中定义的属性创接池对象?nbsp;
3) 实现q接池名字与其实例之间的映射?nbsp;
4) 跟踪客户E序对连接池的引用,保证在最后一个客L序结束时安全地关闭所有连接池?nbsp;

本文余下部分详l说明这两个c,最后给Z个示例演CServlet使用q接池的一般过E?nbsp;


二、具体实?nbsp;

DBConnectionManager.javaE序清单如下Q?nbsp;

001 import java.io.*;
002 import java.sql.*;
003 import java.util.*;
004 import java.util.Date;
005 
006 /** 
007 * 理cDBConnectionManager支持对一个或多个由属性文件定义的数据库连?nbsp;
008 * 池的讉K.客户E序可以调用getInstance()Ҏ讉K本类的唯一实例. 
009 */ 
010 public class DBConnectionManager { 
011 static private DBConnectionManager instance;// 唯一实例 
012 static private int clients;
013 
014 private Vector drivers = new Vector();
015 private PrintWriter log;
016 private Hashtable pools = new Hashtable();
017 
018 /** 
019 * q回唯一实例.如果是第一ơ调用此Ҏ,则创建实?nbsp;
020 * 
021 * @return DBConnectionManager 唯一实例 
022 */ 
023 static synchronized public DBConnectionManager getInstance() { 
024 if (instance == null) { 
025 instance = new DBConnectionManager();
026 } 
027 clients++;
028 return instance;
029 } 
030 
031 /** 
032 * 建构函数U有以防止其它对象创建本cd?nbsp;
033 */ 
034 private DBConnectionManager() { 
035 init();
036 } 
037 
038 /** 
039 * 连接对象返回给由名字指定的q接?nbsp;
040 * 
041 * @param name 在属性文件中定义的连接池名字 
042 * @param con q接对象 
043 */ 
044 public void freeConnection(String name, Connection con) { 
045 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
046 if (pool != null) { 
047 pool.freeConnection(con);
048 } 
049 } 
050 
051 /** 
052 * 获得一个可用的(I闲?q接.如果没有可用q接,且已有连接数于最大连接数 
053 * 限制,则创建ƈq回新连?nbsp;
054 * 
055 * @param name 在属性文件中定义的连接池名字 
056 * @return Connection 可用q接或null 
057 */ 
058 public Connection getConnection(String name) { 
059 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
060 if (pool != null) { 
061 return pool.getConnection();
062 } 
063 return null;
064 } 
065 
066 /** 
067 * 获得一个可用连?若没有可用连?且已有连接数于最大连接数限制, 
068 * 则创建ƈq回新连?否则,在指定的旉内等待其它线E释放连? 
069 * 
070 * @param name q接池名?nbsp;
071 * @param time 以毫U计的等待时?nbsp;
072 * @return Connection 可用q接或null 
073 */ 
074 public Connection getConnection(String name, long time) { 
075 DBConnectionPool pool = (DBConnectionPool) pools.get(name);
076 if (pool != null) { 
077 return pool.getConnection(time);
078 } 
079 return null;
080 } 
081 
082 /** 
083 * 关闭所有连?撤销驱动E序的注?nbsp;
084 */ 
085 public synchronized void release() { 
086 // {待直到最后一个客L序调?nbsp;
087 if (--clients != 0) { 
088 return;
089 } 
090 
091 Enumeration allPools = pools.elements();
092 while (allPools.hasMoreElements()) { 
093 DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
094 pool.release();
095 } 
096 Enumeration allDrivers = drivers.elements();
097 while (allDrivers.hasMoreElements()) { 
098 Driver driver = (Driver) allDrivers.nextElement();
099 try { 
100 DriverManager.deregisterDriver(driver);
101 log("撤销JDBC驱动E序 " + driver.getClass().getName()+"的注?);
102 } 
103 catch (SQLException e) { 
104 log(e, "无法撤销下列JDBC驱动E序的注? " + driver.getClass().getName());
105 } 
106 } 
107 } 
108 
109 /** 
110 * Ҏ指定属性创接池实例. 
111 * 
112 * @param props q接池属?nbsp;
113 */ 
114 private void createPools(Properties props) { 
115 Enumeration propNames = props.propertyNames();
116 while (propNames.hasMoreElements()) { 
117 String name = (String) propNames.nextElement();
118 if (name.endsWith(".url")) { 
119 String poolName = name.substring(0, name.lastIndexOf("."));
120 String url = props.getProperty(poolName + ".url");
121 if (url == null) { 
122 log("没有接池" + poolName + "指定URL");
123 continue;
124 } 
125 String user = props.getProperty(poolName + ".user");
126 String password = props.getProperty(poolName + ".password");
127 String maxconn = props.getProperty(poolName + ".maxconn", "0");
128 int max;
129 try { 
130 max = Integer.valueOf(maxconn).intValue();
131 } 
132 catch (NumberFormatException e) { 
133 log("错误的最大连接数限制: " + maxconn + " .q接? " + poolName);
134 max = 0;
135 } 
136 DBConnectionPool pool = 
137 new DBConnectionPool(poolName, url, user, password, max);
138 pools.put(poolName, pool);
139 log("成功创徏q接? + poolName);
140 } 
141 } 
142 } 
143 
144 /** 
145 * d属性完成初始化 
146 */ 
147 private void init() { 
148 InputStream is = getClass().getResourceAsStream("/db.properties");
149 Properties dbProps = new Properties();
150 try { 
151 dbProps.load(is);
152 } 
153 catch (Exception e) { 
154 System.err.println("不能d属性文? " + 
155 "L保db.properties在CLASSPATH指定的\径中");
156 return;
157 } 
158 String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log");
159 try { 
160 log = new PrintWriter(new FileWriter(logFile, true), true);
161 } 
162 catch (IOException e) { 
163 System.err.println("无法打开日志文g: " + logFile);
164 log = new PrintWriter(System.err);
165 } 
166 loadDrivers(dbProps);
167 createPools(dbProps);
168 } 
169 
170 /** 
171 * 装蝲和注册所有JDBC驱动E序 
172 * 
173 * @param props 属?nbsp;
174 */ 
175 private void loadDrivers(Properties props) { 
176 String driverClasses = props.getProperty("drivers");
177 StringTokenizer st = new StringTokenizer(driverClasses);
178 while (st.hasMoreElements()) { 
179 String driverClassName = st.nextToken().trim();
180 try { 
181 Driver driver = (Driver) 
182 Class.forName(driverClassName).newInstance();
183 DriverManager.registerDriver(driver);
184 drivers.addElement(driver);
185 log("成功注册JDBC驱动E序" + driverClassName);
186 } 
187 catch (Exception e) { 
188 log("无法注册JDBC驱动E序: " + 
189 driverClassName + ", 错误: " + e);
190 } 
191 } 
192 } 
193 
194 /** 
195 * 文本信息写入日志文?nbsp;
196 */ 
197 private void log(String msg) { 
198 log.println(new Date() + ": " + msg);
199 } 
200 
201 /** 
202 * 文本信息与异常写入日志文g 
203 */ 
204 private void log(Throwable e, String msg) { 
205 log.println(new Date() + ": " + msg);
206 e.printStackTrace(log);
207 } 
208 
209 /** 
210 * 此内部类定义了一个连接池.它能够根据要求创建新q接,直到预定的最 
211 * 大连接数为止.在返回连接给客户E序之前,它能够验证连接的有效? 
212 */ 
213 class DBConnectionPool { 
214 private int checkedOut;
215 private Vector freeConnections = new Vector();
216 private int maxConn;
217 private String name;
218 private String password;
219 private String URL;
220 private String user;
221 
222 /** 
223 * 创徏新的q接?nbsp;
224 * 
225 * @param name q接池名?nbsp;
226 * @param URL 数据库的JDBC URL 
227 * @param user 数据库帐??nbsp;null 
228 * @param password 密码,?nbsp;null 
229 * @param maxConn 此连接池允许建立的最大连接数 
230 */ 
231 public DBConnectionPool(String name, String URL, String user, String password, 
232 int maxConn) { 
233 this.name = name;
234 this.URL = URL;
235 this.user = user;
236 this.password = password;
237 this.maxConn = maxConn;
238 } 
239 
240 /** 
241 * 不再用的q接q回l连接池 
242 * 
243 * @param con 客户E序释放的连?nbsp;
244 */ 
245 public synchronized void freeConnection(Connection con) { 
246 // 指定连接加入到向量末尾 
247 freeConnections.addElement(con);
248 checkedOut--;
249 notifyAll();
250 } 
251 
252 /** 
253 * 从连接池获得一个可用连?如没有空闲的q接且当前连接数于最大连?nbsp;
254 * 数限?则创建新q接.如原来登Cؓ可用的连接不再有?则从向量删除? 
255 * 然后递归调用自己以尝试新的可用连? 
256 */ 
257 public synchronized Connection getConnection() { 
258 Connection con = null;
259 if (freeConnections.size()>
0) { 
260 // 获取向量中第一个可用连?nbsp;
261 con = (Connection) freeConnections.firstElement();
262 freeConnections.removeElementAt(0);
263 try { 
264 if (con.isClosed()) { 
265 log("从连接池" + name+"删除一个无效连?);
266 // 递归调用自己,试再次获取可用q接 
267 con = getConnection();
268 } 
269 } 
270 catch (SQLException e) { 
271 log("从连接池" + name+"删除一个无效连?);
272 // 递归调用自己,试再次获取可用q接 
273 con = getConnection();
274 } 
275 } 
276 else if (maxConn == 0 || checkedOut
<maxConn) { 
277 con = newConnection(); 
278 } 
279 if (con != null) { 
280 checkedOut++; 
281 } 
282 return con; 
283 } 
284 
285 /** 
286 * 从连接池获取可用q接.可以指定客户E序能够{待的最长时?nbsp;
287 * 参见前一个getConnection()Ҏ. 
288 * 
289 * @param timeout 以毫U计的等待时间限?nbsp;
290 */ 
291 public synchronized Connection getConnection(long timeout) { 
292 long startTime = new Date().getTime(); 
293 Connection con; 
294 while ((con = getConnection()) == null) { 
295 try { 
296 wait(timeout); 
297 } 
298 catch (InterruptedException e) {} 
299 if ((new Date().getTime() - startTime)>
= timeout) { 
300 // wait()q回的原因是时 
301 return null;
302 } 
303 } 
304 return con;
305 } 
306 
307 /** 
308 * 关闭所有连?nbsp;
309 */ 
310 public synchronized void release() { 
311 Enumeration allConnections = freeConnections.elements();
312 while (allConnections.hasMoreElements()) { 
313 Connection con = (Connection) allConnections.nextElement();
314 try { 
315 con.close();
316 log("关闭q接? + name+"中的一个连?);
317 } 
318 catch (SQLException e) { 
319 log(e, "无法关闭q接? + name+"中的q接");
320 } 
321 } 
322 freeConnections.removeAllElements();
323 } 
324 
325 /** 
326 * 创徏新的q接 
327 */ 
328 private Connection newConnection() { 
329 Connection con = null;
330 try { 
331 if (user == null) { 
332 con = DriverManager.getConnection(URL);
333 } 
334 else { 
335 con = DriverManager.getConnection(URL, user, password);
336 } 
337 log("q接? + name+"创徏一个新的连?);
338 } 
339 catch (SQLException e) { 
340 log(e, "无法创徏下列URL的连? " + URL);
341 return null;
342 } 
343 return con;
344 } 
345 } 
346 } 


三、类DBConnectionPool说明 

该类?09?45行实玎ͼ它表C指向某个数据库的连接池。数据库由JDBC URL标识。一个JDBC URL׃部分l成Q协议标识(LjdbcQ,驱动E序标识Q如 odbc、idb、oracle{)Q数据库标识Q其格式依赖于驱动程序)。例如,jdbc:odbc:demoQ即是一个指向demo数据库的JDBC URLQ而且讉K该数据库要用JDBC-ODBC驱动E序。每个连接池都有一个供客户E序使用的名字以及可选的用户帐号、密码、最大连接数限制。如果Web应用E序所支持的某些数据库操作可以被所有用h行,而其它一些操作应q别许可的用户执行Q则可以ZcL作分别定义连接池Q两个连接池使用相同的JDBC URLQ但使用不同的帐号和密码?nbsp;
cDBConnectionPool的徏构函数需要上q所有数据作为其参数。如222?38行所C,q些数据被保存ؓ它的实例变量Q?nbsp;
?52?83行?85?05行所C, 客户E序可以使用DBConnectionPoolcL供的两个Ҏ获取可用q接。两者的共同之处在于Q如q接池中存在可用q接Q则直接q回Q否则创建新的连接ƈq回。如果没有可用连接且已有q接L{于最大限制数Q第一个方法将直接q回nullQ而第二个Ҏ等待直到有可用q接为止?nbsp;
所有的可用q接对象均登记在名ؓfreeConnections的向量(VectorQ中。如果向量中有多于一个的q接QgetConnection()L选取W一个。同Ӟ׃新的可用q接L从尾部加入向量,从而得数据库q接׃长时间闲|而被关闭的风险减低到最程度?nbsp;
W一个getConnection()在返回可用连接给客户E序之前Q调用了isClosed()Ҏ验证q接仍旧有效。如果该q接被关闭或触发异常QgetConnection()递归地调用自׃试获取另外的可用连接。如果在向量freeConnections中不存在M可用q接QgetConnection()Ҏ查是否已l指定最大连接数限制。如已经指定Q则查当前连接数是否已经到达极限。此处maxConn?表示没有限制。如果没有指定最大连接数限制或当前连接数于该|该方法尝试创建新的连接。如创徏成功Q则增加已用连接的计数q返回,否则q回I倹{?nbsp;
?25?45行所C,创徏新连接由newConnection()Ҏ实现。创E与是否已经指定数据库帐受密码有兟?nbsp;
JDBC的DriverManagercL供多个getConnection()ҎQ这些方法要用到JDBC URL与其它一些参敎ͼ如用户帐号和密码{。DriverManager用指定的JDBC URL定适合于目标数据库的驱动程序及建立q接?nbsp;
?85?05行实现的W二个getConnection()Ҏ需要一个以毫秒为单位的旉参数Q该参数表示客户E序能够{待的最长时间。徏立连接的具体操作仍旧q一个getConnection()Ҏ实现?nbsp;
该方法执行时先将startTime初始化ؓ当前旉。在while循环中尝试获得一个连接。如果失败,则以l定的时间gؓ参数调用wait()。wait()的返回可能是׃其它U程调用notify()或notifyAll()Q也可能是由于预定时间已到。ؓ扑ևwait()q回的真正原因,E序用当前时间减开始时_startTimeQ,如差值大于预定时间则q回I|否则再次调用getConnection()?nbsp;
把空闲的q接登记到连接池?40?50行的freeConnection()Ҏ实现Q它的参Cؓq回l连接池的连接对象。该对象被加入到freeConnections向量的末,然后减少已用连接计数。调用notifyAll()是ؓ了通知其它正在{待可用q接的线E?nbsp;
许多Servlet引擎为实现安全关闭提供多U方法。数据库q接池需要知道该事g以保证所有连接能够正常关闭。DBConnectionManagerc负协调整个关闭q程Q但关闭q接池中所有连接的d则由DBConnectionPoolc负责。在307?23行实现的release()Ҏ供DBConnectionManager调用。该Ҏ遍历freeConnections向量q关闭所有连接,然后从向量中删除q些q接?nbsp;


四、类DBConnectionManager 说明 

该类只能创徏一个实例,其它对象能够调用光态方法(也称为类ҎQ获得该唯一实例的引用。如031?36行所C,DBConnectionManagercȝ建构函数是私有的Q这是ؓ了避免其它对象创cȝ实例?nbsp;
DBConnectionManagercȝ客户E序可以调用getInstance()Ҏ获得对该cd一实例的引用。如018?29行所C,cȝ唯一实例在getInstance()ҎW一ơ被调用期间创徏Q此后其引用׃直保存在静态变量instance中。每ơ调用getInstance()都增加一个DBConnectionManager的客L序计数。即Q该计数代表引用DBConnectionManager唯一实例的客L序LQ它被用于控制q接池的关闭操作?nbsp;
该类实例的初始化工作?46?68行之间的U有Ҏinit()完成。其?nbsp;getResourceAsStream()Ҏ用于定位q打开外部文g。外部文件的定位Ҏ依赖于类装蝲器的实现。标准的本地c装载器查找操作L开始于cL件所在\径,也能够搜索CLASSPATH中声明的路径。db.properties是一个属性文Ӟ它包含定义连接池的键-值对。可供定义的公用属性如下: 

drivers 以空格分隔的JDBC驱动E序cd?nbsp;
logfile 日志文g的绝对\?nbsp;

其它的属性和特定q接池相养I其属性名字前应加上连接池名字Q?BR><poolname>
.url 数据库的 JDBC URL
<poolname>
.maxconn 允许建立的最大连接数Q?表示没有限制
<poolname>
.user 用于该连接池的数据库帐号
<poolname>
.password 相应的密?nbsp;

其中url属性是必需的,而其它属性则是可选的。数据库帐号和密码必d法。用于Windowsq_的db.properties文gCZ如下Q?nbsp;

drivers=sun.jdbc.odbc.JdbcOdbcDriver jdbc.idbDriver 
logfile=D:\\user\\src\\java\\DBConnectionManager\\log.txt 

idb.url=jdbc:idb:c:\\local\\javawebserver1.1\\db\\db.prp 
idb.maxconn=2 

access.url=jdbc:odbc:demo 
access.user=demo 
access.password=demopw 

注意在Windows路径中的反斜杠必输?个,q是׃属性文件中的反斜杠同时也是一个{义字W?nbsp;
init()Ҏ在创建属性对象ƈddb.properties文g之后Q就开始检查logfile属性。如果属性文件中没有指定日志文gQ则默认为当前目录下的DBConnectionManager.log文g。如日志文g无法使用Q则向System.err输出日志记录?nbsp;
装蝲和注册所有在drivers属性中指定的JDBC驱动E序?70?92行之间的loadDrivers()Ҏ实现。该Ҏ先用StringTokenizerdrivers属性值分割ؓ对应于驱动程序名U的字符Ԍ然后依次装蝲q些cdƈ创徏其实例,最后在 DriverManager中注册该实例q把它加入到一个私有的向量drivers。向量drivers用于关闭服务时从DriverManager取消所有JDBC 驱动E序的注册?nbsp;
init()Ҏ的最后一个Q务是调用U有ҎcreatePools()创徏q接池对象。如109?42行所C,createPools()Ҏ先创建所有属性名字的枚D对象Q即Enumeration对象Q该对象可以惌Z个元素系列,逐次调用其nextElement()Ҏ顺序返回各元素Q,然后在其中搜索名字以?url”结属性。对于每一个符合条件的属性,先提取其q接池名字部分,q而读取所有属于该q接池的属性,最后创接池对象q把它保存在实例变量pools中。散列表QHashtablec?nbsp;Qpools实现q接池名字到q接池对象之间的映射Q此处以q接池名字ؓ键,q接池对象ؓ倹{?nbsp;
Z于客L序从指定q接池获得可用连接或连接返回给q接池,cDBConnectionManager提供了方法getConnection()和freeConnection()。所有这些方法都要求在参C指定q接池名字,具体的连接获取或q回操作则调用对应的q接池对象完成。它们的实现分别?51?64行?66?80行?38?49行?nbsp;
?82?07行所C,为实现连接池的安全关闭,DBConnectionManager提供了方法release()。在上面我们已经提到Q所有DBConnectionManager的客L序都应该调用静态方法getInstance()以获得该理器的引用Q此调用增加客L序计数。客L序在关闭时调用release()可以递减该计数。当最后一个客L序调用release()Q递减后的引用计数?Q就可以调用各个q接池的release()Ҏ关闭所有连接了。管理类release()Ҏ最后的d是撤销所有JDBC驱动E序的注册?nbsp;


五、Servlet使用q接池示?nbsp;

Servlet API所定义的Servlet生命周期cdQ?nbsp;

1) 创徏q初始化ServletQinit()ҎQ?nbsp;
2) 响应客户E序的服务请求(service()ҎQ?nbsp;
3) Servletl止q行Q释放所有资源(destroy()ҎQ?nbsp;

本例演示q接池应用,上述关键步骤中的相关操作为: 

1) 在init()Q用实例变量connMgr 保存调用DBConnectionManager.getInstance()所q回的引用?nbsp;
2) 在service()Q调用getConnection()Q执行数据库操作Q用freeConnection()连接返回给q接池?nbsp;
3) 在destroy()Q调用release()关闭所有连接,释放所有资源?nbsp;

CZE序清单如下Q?nbsp;

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TestServlet extends HttpServlet { 
private DBConnectionManager connMgr;

public void init(ServletConfig conf) throws ServletException { 
super.init(conf);
connMgr = DBConnectionManager.getInstance();


public void service(HttpServletRequest req, HttpServletResponse res) 
throws IOException { 

res.setContentType("text/html");
PrintWriter out = res.getWriter();
Connection con = connMgr.getConnection("idb");
if (con == null) { 
out.println("不能获取数据库连?");
return;

ResultSet rs = null;
ResultSetMetaData md = null;
Statement stmt = null;
try { 
stmt = con.createStatement();
rs = stmt.executeQuery("SELECT * FROM EMPLOYEE");
md = rs.getMetaData();
out.println("
<H1>
职工数据
</H1>
");
while (rs.next()) { 
out.println("
<BR>
");
for (int i = 1;i"
<md.getColumnCount();i++) { 
out.print(rs.getString(i) + ", ");


stmt.close();
rs.close();

catch (SQLException e) { 
e.printStackTrace(out);

connMgr.freeConnection("idb", con);


public void destroy() { 
connMgr.release();
super.destroy();

}


不行Q这不是我要扄Q我要再?A HREF="/searchInternet.asp?query=用连接池提高Servlet讉K数据库的效率" target=_blank>从互联网上搜索与此相关的内容


aiyoyoyo 2006-02-17 16:43 发表评论
]]>
java解决国际化问题(ResourceBundleQ?/title><link>http://www.aygfsteel.com/aiyoyoyo/articles/31215.html</link><dc:creator>aiyoyoyo</dc:creator><author>aiyoyoyo</author><pubDate>Fri, 17 Feb 2006 08:12:00 GMT</pubDate><guid>http://www.aygfsteel.com/aiyoyoyo/articles/31215.html</guid><wfw:comment>http://www.aygfsteel.com/aiyoyoyo/comments/31215.html</wfw:comment><comments>http://www.aygfsteel.com/aiyoyoyo/articles/31215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/aiyoyoyo/comments/commentRss/31215.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/aiyoyoyo/services/trackbacks/31215.html</trackback:ping><description><![CDATA[<H3 class=title>    在用Java解决国际化问题的q程中,可能利用到的主要的类都是由java.util包提供的。该cd中相关的cLLocale、ResourceBundle、ListResourceBundle、PropertyResourceBundle{?BR>    LocaleQ该cd含对主要地理区域的地域化特征的封装。其特定对象表示某一特定的地理、政L文化区域。通过讑֮LocaleQ我们可以ؓ特定的国家或地区提供W合当地文化习惯的字体、符受图标和表达格式。例如,我们可以通过获得特定Locale下的Calendarcȝ实例Q显C符合特定表达格式的日期?BR>    ResourceBundleQ该cL一个抽象类Q需要通过静态方法ResourceBundle.getBundle()指定具体实现cL属性文件的基本名称。基本名UC协同指定的或默认的Localec,军_具体调用的类或属性文件的唯一名称。例如:指定基本cL属性文件名UCؓTestBundleQ而指定的Locale是CHINESEQ那么最适合匚w的类名称为TestBundle_zh_CN.classQ而最佛_配属性文件名UCؓTestBundle_zh_CN.properties。按照Java Doc和相x档的要求Q如果该cL属性文件没有找刎ͼpȝ会查找近似匹配(L件名依次为TestBundle_zh和TestBundle的类或属性文Ӟ。该cL供的getKeys()Ҏ用于获得所有成员的键名Qƈ提供handleGetObjectҎ获得指定键的对应元素?BR>    ListResourceBundleQ该cȝ承ResourceBundlec,主要是增加了一些便于操作的成分Q但q是抽象cR如果希望用类的方式实现具体的ResourceBundleQ一般情况下最好承这个类?BR>    PropertyResourceBundleQ该cMl承ResourceBundlec,可以实例化。该cȝ行ؓ特征如同java.util.propertiesc,可以从输入流中获得具体属性对?BR>    使用PropertyResourceBundlec获得当地版本的国际化信息,部分代码如下…?BR>    public static final String BASE_PROP_FILE = “DISP?<BR>  public static final String SUFFIX = ?properties?<BR>  locale = Locale.getDefault();<BR>  String propFile = BASE_PROP_FILE Q?“_?Q?locale.toString()Q?SUFFIX;<BR>  ResourceBundle rb;<BR>  try {<BR>   File file = new File(propFile);<BR>   if (file.exists()) {<BR>     is = new FileInputStream(file);<BR>      rb = new PropertyResourceBundle(is);<BR>      if (rb == null) System.out.println(“No Resource?;<BR>   }<BR>  } catch (IOException ioe) {<BR>   System.out.println(“Error open file named ?Q?propFile);<BR>  }<BR>  Enumeration e = rb.getKeys();<BR>  while (e.hasMoreElements()){<BR>   key = (String)e.nextElement();<BR>   value = (String)rb.handleGetObject(key); <BR>   System.out.println(“KEY: ?Q?key Q?Value: ?Q?value);<BR>  }<BR>  …?BR>  DISP_zh_TW.properties文g的具体内容如下:<BR>  Key1=可以<BR>  Key2=撤销<BR>    {号后面是利用native2asciiE序转化后的J体汉字Q如果不q行转化Q系l可能显CZؕ码?BR>     <BR>    处理提示和帮?BR>    对于提示语言和帮助文仉分,可以把语a映射攑֜属性文件或者ListResourceBundlecȝ子类中。下面程序是一个ServletQ它通过接受客户端的选择Q把特定语言和字W版本的信息q回到客L。  public class ProcessServlet extends HttpServlet <BR>  { //默认语言Z?BR>   public static final String DEFAULT_LANGUAGE = “zh? <BR>   //默认字符集ؓ体中?BR>   public static final String DEFAULT_COUNTRY = “CN? <BR>   public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {<BR>   HttpSession session = req.getSession(true);<BR>   // 从客L收到的指定语a和字W的参数应当与Sun公司相关规定一?BR>   String lang = req.getParameter(“language?;<BR>   String country = req.getParameter(“country?;<BR>   if (lang == null) {<BR>       //如果没有收到参数Q就试图从Session里获?BR>     lang = (String) session.getAttribute(“language?;<BR>     country = (String) session.getAttribute(“country?;<BR>   } else {<BR>     session.setAttribute(“language? lang);<BR>     session.setAttribute(“country? country);<BR>   }<BR>   if (lang == null){<BR>       //如果无法从上q手D得到语a和字W信息,׃用默认?BR>     lang = DEFAULT_LANGUAGE;<BR>     country = DEFAULT_COUNTRY<BR>     session.setAttribute(“language? lang);<BR>    session.setAttribute(“country? country);<BR>   }<BR>   Locale locale = null;<BR>   ResourceBundle bundle = null;<BR>   try {<BR>     locale = new Locale(lang, country);<BR>    } catch (Exception e) {<BR>      System.out.println(“No locale with?Q?country Q?“_?Q?lang);<BR>     locale = Locale.getDefault();<BR>    }<BR>    try {<BR>       bundle = ResourceBundle.getBundle(“DisplayList? locale);<BR>   } catch( MissingResourceException e) {<BR>     System.out.println( “No resources available for locale ?Q?locale);<BR>     bundle = ResourceBundle.getBundle(“DisplayList? Locale.US);<BR>   }<BR>   res.setContentType(“text/html?;<BR>   PrintWriter out = res.getWriter();<BR>   out.println(?amp;lt;html&gt;?;<BR>   out.println(?amp;lt;head&gt;?;<BR>   String title = bundle.getString(“title?;<BR>    String welcome =bundle.getString(“welcome?;<BR>   String notice = bundle.getString(“notice?;<BR>   out.println(?amp;lt;title&gt;”+ title Q?amp;lt;/title&gt;?;<BR>   out.println(?amp;lt;/head&gt;?;<BR>   out.println(?amp;lt;body bgcolor=”white?amp;gt;?;<BR>   out.println(?amp;lt;h3&gt;?Q?welcome Q??amp;lt;/h3&gt;?;<BR>   out.println(?amp;lt;br&gt;?;<BR>   out.println(?amp;lt;b&gt;?Q?notice Q?amp;lt;/b&gt;?;<BR>   out.println(?amp;lt;/body&gt;?;<BR>   out.println(?amp;lt;/html&gt;?;<BR>  }<BR>  }<BR>上述Servlet使用的属性文ӞDisplayList_zh_CN.propertiesQ内容如下:<BR>title=中文?BR>welcome=q是体中文版?BR>notice=体中文测试成?BR>注意Q该文g直接采用了中文,而不是经q{化的Unicode~码Q这是由于大多数Web服务器不需要上q{化?BR>    在实际用中Q如果Web服务器支持Servlet 2.3规范Q如jakartaQtomcate 4.0Q,那么上面提到的Servlet应当E加改变Q以作ؓ其他Servlet的处理器使用。另外,如果把ResourceBundle的特定版本存攑֜无状态会话Bean中,可以在一定程度上提高E序效率?BR>    对于昄字符出现q的问题,如果是通过属性文件实现国际化解决ҎQ那么可能是直接在属性文件中写入了非标准ASCII文字。解x法是利用JDK提供的工具native2ascii.exe扫描所有属性文Ӟ用扫描结果覆盖原有文件内宏V如果我们是利用cL件实现{换方案,那么需要重新编译相关类文gQƈ在编译时指定~码集。例如,~译使用国标码的cLӞ采用的编译命令如下:<BR>javac Qencoding GB2312 your_java_file</H3><img src ="http://www.aygfsteel.com/aiyoyoyo/aggbug/31215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/aiyoyoyo/" target="_blank">aiyoyoyo</a> 2006-02-17 16:12 <a href="http://www.aygfsteel.com/aiyoyoyo/articles/31215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSPq解决Q过虑器EncodingFilterQ?/title><link>http://www.aygfsteel.com/aiyoyoyo/articles/31211.html</link><dc:creator>aiyoyoyo</dc:creator><author>aiyoyoyo</author><pubDate>Fri, 17 Feb 2006 08:06:00 GMT</pubDate><guid>http://www.aygfsteel.com/aiyoyoyo/articles/31211.html</guid><wfw:comment>http://www.aygfsteel.com/aiyoyoyo/comments/31211.html</wfw:comment><comments>http://www.aygfsteel.com/aiyoyoyo/articles/31211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/aiyoyoyo/comments/commentRss/31211.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/aiyoyoyo/services/trackbacks/31211.html</trackback:ping><description><![CDATA[<P>做JSPE序旉面传的文字经常是qQ如何解军_Q?/P> <P>一U方法是把tomcat中所有的<Connector>标签的URIEncoding属性进行设|?? <Connector port="8000" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK" /></P> <P>而另一U方法就是写qo?/P> <P>import javax.servlet.*;<BR>import javax.servlet.http.HttpServletRequest;<BR>import java.io.IOException;</P> <P>public class EncodingFilter implements Filter {<BR>    FilterConfig config = null;<BR>    // default to GBK<BR>    private String targetEncoding = "GBK";</P> <P>    public void init(FilterConfig config) throws ServletException {<BR>        this.config = config;<BR>        this.targetEncoding = config.getInitParameter("encoding");<BR>    }</P> <P>    public void destroy() {<BR>        config = null;<BR>        targetEncoding = null;<BR>    }</P> <P>    public void doFilter(ServletRequest srequest, ServletResponse sresponse,<BR>                         FilterChain chain) throws IOException, ServletException {</P> <P>        HttpServletRequest request = (HttpServletRequest)srequest;<BR>        request.setCharacterEncoding(targetEncoding);<BR>        chain.doFilter(srequest, sresponse);<BR>    }<BR>}</P> <P>配置Q在web.xml中添?BR>    <filter><BR>        <filter-name>encodingFilter</filter-name><BR>        <filter-class>xx.xx.xx.EncodingFilter</filter-class><BR>        <init-param><BR>            <param-name>encoding</param-name><BR>            <param-value>Shift_JIS</param-value><BR>        </init-param><BR>        <init-param><BR>            <param-name>useragents</param-name><BR>            <param-value>Mac</param-value><BR>        </init-param><BR>    </filter><BR><BR>    <filter-mapping><BR>        <filter-name>encodingFilter</filter-name><BR>        <url-pattern>/*</url-pattern><BR>    </filter-mapping><BR><BR>至于来自何处Q忘C。嘿ѝ。?/P><img src ="http://www.aygfsteel.com/aiyoyoyo/aggbug/31211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/aiyoyoyo/" target="_blank">aiyoyoyo</a> 2006-02-17 16:06 <a href="http://www.aygfsteel.com/aiyoyoyo/articles/31211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">®</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͨ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̨ǰ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">մ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̨</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ຣʡ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͩ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ȫ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">«ɽ</a>| <a href="http://" target="_blank">ʲ</a>| <a href="http://" target="_blank">Զ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">Ĭ</a>| <a href="http://" target="_blank">첼</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>