proxool是个很好的开源连接池。但配置文件中的用户和密码却是明文存储的,如果对系统安全有较高的要求,使用时就麻烦了。昨天下了Proxool 0.9.1的源码,研究了下,做了些小小的改动,现在proxool配置文件中用户和密码可以使用密文存储了,同时明文的也可以正常使用。解密功能部分做成了接口,可以用自己的算法来实现,很方便。
先上配置文件proxool.xml
<?xml version="1.0" encoding="gb2312"?> <!-- the proxool configuration can be embedded within your own application's. Anything outside the "proxool" tag is ignored. --> <something-else-entirely> <proxool> <!--连接池的别名--> <alias>hdqt</alias> <!--实现解密的工具类--> <encrypt>cn.bq.tools.DecUtil</encrypt> <!--proxool只能管理由自己产生的连接--> <driver-url>jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=xxxx</driver-url> <!--JDBC驱动程序--> <driver-class>com.microsoft.jdbc.sqlserver.SQLServerDriver</driver-class> <driver-properties> <!--加密后的用户名和密码--> <property name="user" value="da33e8657877280c32683ae317ef78e1"/> <property name="password" value="3defde98af47835a74537600eebe78f2"/> </driver-properties> <!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁--> <house-keeping-sleep-time>90000</house-keeping-sleep-time> <house-keeping-test-sql>select getdate()</house-keeping-test-sql> <!-- 指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受--> <!--maximum-new-connections>150</maximum-new-connections--> <simultaneous-build-throttle>5</simultaneous-build-throttle> <!-- 最少保持的空闲连接数--> <prototype-count>3</prototype-count> <!-- 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定--> <maximum-connection-count>100</maximum-connection-count> <!-- 最小连接数--> <minimum-connection-count>3</minimum-connection-count> </proxool> </something-else-entirely>
proxool.properties配置文件:
jdbc-0.proxool.alias=property-test jdbc-0.encrypt=cn.bq.tools.DecUtil jdbc-0.proxool.driver-url=jdbc:sqlserver://127.0.0.1:1433;databaseName=xxxx jdbc-0.proxool.driver-class=com.microsoft.jdbc.sqlserver.SQLServerDriver jdbc-0.user=da33e8657877280c32683ae317ef78e1 jdbc-0.password=3defde98af47835a74537600eebe78f2 jdbc-0.proxool.house-keeping-sleep-time=40000 jdbc-0.proxool.house-keeping-test-sql=select getdate() jdbc-0.proxool.maximum-connection-count=10 jdbc-0.proxool.minimum-connection-count=3 jdbc-0.proxool.maximum-connection-lifetime=18000000 jdbc-0.proxool.simultaneous-build-throttle=5 jdbc-0.proxool.recently-started-threshold=40000 jdbc-0.proxool.overload-without-refusal-lifetime=50000 jdbc-0.proxool.maximum-active-time=60000 jdbc-0.proxool.verbose=true jdbc-0.proxool.trace=true jdbc-0.proxool.fatal-sql-exception=Fatal error jdbc-0.proxool.prototype-count=2
下面是修改的类:
ProxoolConstants.java
/* * This software is released under a licence similar to the Apache Software Licence. * See org.logicalcobwebs.proxool.package.html for details. * The latest version is available at http://proxool.sourceforge.net */ package org.logicalcobwebs.proxool; /** * All constants here please. * * @version $Revision: 1.21 $, $Date: 2004/06/02 20:39:17 $ * @author billhorsman * @author $Author: billhorsman $ (current maintainer) */ public interface ProxoolConstants { public final String PROXOOL = "proxool"; /** * The namespace uri associated with namepace aware Proxool xml configurations.<br> * Value: The latest version is available at http://proxool.sourceforge.net/xml-namespace */ public final String PROXOOL_XML_NAMESPACE_URI = "The latest version is available at http://proxool.sourceforge.net/xml-namespace"; public final String ALIAS_DELIMITER = "."; public final String PROPERTY_PREFIX = PROXOOL + "."; public final String URL_DELIMITER = ":"; /** 用户名和密码是否加密,对应值为解密的class*/ public final String USER_PASSWORD_ENCRYPT = "encrypt"; /** Standard JDBC property */ public final String USER_PROPERTY = "user"; /** Standard JDBC property */ public final String PASSWORD_PROPERTY = "password"; /** Used to build up URL */ public final String ALIAS_PROPERTY = PROPERTY_PREFIX + "alias"; /** Instead of defining the driver in the url you can also use this property */ public final String DELEGATE_DRIVER = "driver"; /** @see ProxoolDriver#getPropertyInfo */ public final String DELEGATE_DRIVER_PROPERTY = PROPERTY_PREFIX + DELEGATE_DRIVER; /** @see #HOUSE_KEEPING_SLEEP_TIME_PROPERTY */ public final String DELEGATE_URL = "url"; /** @see ProxoolDriver#getPropertyInfo */ public final String DELEGATE_URL_PROPERTY = PROPERTY_PREFIX + DELEGATE_URL; /** @see #HOUSE_KEEPING_SLEEP_TIME_PROPERTY */ public final String HOUSE_KEEPING_SLEEP_TIME = "house-keeping-sleep-time"; /** @see ProxoolDriver#getPropertyInfo */ public final String HOUSE_KEEPING_SLEEP_TIME_PROPERTY = PROPERTY_PREFIX + HOUSE_KEEPING_SLEEP_TIME; /** @see #HOUSE_KEEPING_TEST_SQL_PROPERTY */ public final String HOUSE_KEEPING_TEST_SQL = "house-keeping-test-sql"; /** @see ProxoolDriver#getPropertyInfo */ public final String HOUSE_KEEPING_TEST_SQL_PROPERTY = PROPERTY_PREFIX + HOUSE_KEEPING_TEST_SQL; /** @see #TEST_BEFORE_USE_PROPERTY */ public final String TEST_BEFORE_USE = "test-before-use"; /** @see ProxoolDriver#getPropertyInfo */ public final String TEST_BEFORE_USE_PROPERTY = PROPERTY_PREFIX + TEST_BEFORE_USE; /** @see #TEST_AFTER_USE_PROPERTY */ public final String TEST_AFTER_USE = "test-after-use"; /** @see ProxoolDriver#getPropertyInfo */ public final String TEST_AFTER_USE_PROPERTY = PROPERTY_PREFIX + TEST_AFTER_USE; /** @see #MAXIMUM_CONNECTION_COUNT_PROPERTY */ public final String MAXIMUM_CONNECTION_COUNT = "maximum-connection-count"; /** @see ProxoolDriver#getPropertyInfo */ public final String MAXIMUM_CONNECTION_COUNT_PROPERTY = PROPERTY_PREFIX + MAXIMUM_CONNECTION_COUNT; /** @see #MAXIMUM_CONNECTION_LIFETIME_PROPERTY */ public final String MAXIMUM_CONNECTION_LIFETIME = "maximum-connection-lifetime"; /** @see ProxoolDriver#getPropertyInfo */ public final String MAXIMUM_CONNECTION_LIFETIME_PROPERTY = PROPERTY_PREFIX + MAXIMUM_CONNECTION_LIFETIME; /** * @deprecated use {@link #SIMULTANEOUS_BUILD_THROTTLE} instead */ public final String MAXIMUM_NEW_CONNECTIONS = "maximum-new-connections"; /** * @deprecated use {@link #SIMULTANEOUS_BUILD_THROTTLE_PROPERTY} instead */ public final String MAXIMUM_NEW_CONNECTIONS_PROPERTY = PROPERTY_PREFIX + MAXIMUM_NEW_CONNECTIONS; /** @see #SIMULTANEOUS_BUILD_THROTTLE_PROPERTY*/ public final String SIMULTANEOUS_BUILD_THROTTLE = "simultaneous-build-throttle"; /** @see ProxoolDriver#getPropertyInfo */ public final String SIMULTANEOUS_BUILD_THROTTLE_PROPERTY = PROPERTY_PREFIX + SIMULTANEOUS_BUILD_THROTTLE; /** @see #MINIMUM_CONNECTION_COUNT_PROPERTY */ public final String MINIMUM_CONNECTION_COUNT = "minimum-connection-count"; /** @see ProxoolDriver#getPropertyInfo */ public final String MINIMUM_CONNECTION_COUNT_PROPERTY = PROPERTY_PREFIX + MINIMUM_CONNECTION_COUNT; /** @see #PROTOTYPE_COUNT_PROPERTY */ public final String PROTOTYPE_COUNT = "prototype-count"; /** @see ProxoolDriver#getPropertyInfo */ public final String PROTOTYPE_COUNT_PROPERTY = PROPERTY_PREFIX + PROTOTYPE_COUNT; /** @see #RECENTLY_STARTED_THRESHOLD_PROPERTY */ public final String RECENTLY_STARTED_THRESHOLD = "recently-started-threshold"; /** @see ProxoolDriver#getPropertyInfo */ public final String RECENTLY_STARTED_THRESHOLD_PROPERTY = PROPERTY_PREFIX + RECENTLY_STARTED_THRESHOLD; /** @see #OVERLOAD_WITHOUT_REFUSAL_LIFETIME_PROPERTY */ public final String OVERLOAD_WITHOUT_REFUSAL_LIFETIME = "overload-without-refusal-lifetime"; /** @see ProxoolDriver#getPropertyInfo */ public final String OVERLOAD_WITHOUT_REFUSAL_LIFETIME_PROPERTY = PROPERTY_PREFIX + OVERLOAD_WITHOUT_REFUSAL_LIFETIME; /** @see #MAXIMUM_ACTIVE_TIME_PROPERTY */ public final String MAXIMUM_ACTIVE_TIME = "maximum-active-time"; /** @see ProxoolDriver#getPropertyInfo */ public final String MAXIMUM_ACTIVE_TIME_PROPERTY = PROPERTY_PREFIX + MAXIMUM_ACTIVE_TIME; /** @see #INJECTABLE_CONNECTION_INTERFACE_NAME_PROPERTY */ public final String INJECTABLE_CONNECTION_INTERFACE_NAME = "injectable-connection-interface"; /** @see ProxoolDriver#getPropertyInfo */ public final String INJECTABLE_CONNECTION_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_CONNECTION_INTERFACE_NAME; /** @see #INJECTABLE_STATEMENT_INTERFACE_NAME_PROPERTY */ public final String INJECTABLE_STATEMENT_INTERFACE_NAME = "injectable-statement-interface"; /** @see ProxoolDriver#getPropertyInfo */ public final String INJECTABLE_STATEMENT_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_STATEMENT_INTERFACE_NAME; /** @see #INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME_PROPERTY */ public final String INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME = "injectable-prepared-statement-interface"; /** @see ProxoolDriver#getPropertyInfo */ public final String INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_PREPARED_STATEMENT_INTERFACE_NAME; /** @see #INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME_PROPERTY */ public final String INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME = "injectable-callable-statement-interface"; /** @see ProxoolDriver#getPropertyInfo */ public final String INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME_PROPERTY = PROPERTY_PREFIX + INJECTABLE_CALLABLE_STATEMENT_INTERFACE_NAME; /** * @deprecated use {@link #VERBOSE_PROPERTY verbose} instead. */ public final String DEBUG_LEVEL_PROPERTY = PROPERTY_PREFIX + "debug-level"; /** @see #VERBOSE_PROPERTY */ public final String VERBOSE = "verbose"; /** @see ProxoolDriver#getPropertyInfo */ public final String VERBOSE_PROPERTY = PROPERTY_PREFIX + VERBOSE; /** @see #TRACE_PROPERTY */ public final String TRACE = "trace"; /** @see ProxoolDriver#getPropertyInfo */ public final String TRACE_PROPERTY = PROPERTY_PREFIX + TRACE; /** @see #FATAL_SQL_EXCEPTION_PROPERTY **/ public final String FATAL_SQL_EXCEPTION = "fatal-sql-exception"; /** @see ProxoolDriver#getPropertyInfo */ public final String FATAL_SQL_EXCEPTION_PROPERTY = PROPERTY_PREFIX + FATAL_SQL_EXCEPTION; /** @see #FATAL_SQL_EXCEPTION_WRAPPER_CLASS_PROPERTY**/ public final String FATAL_SQL_EXCEPTION_WRAPPER_CLASS = "fatal-sql-exception-wrapper-class"; /** @see ProxoolDriver#getPropertyInfo */ public final String FATAL_SQL_EXCEPTION_WRAPPER_CLASS_PROPERTY = PROPERTY_PREFIX + FATAL_SQL_EXCEPTION_WRAPPER_CLASS; public static final String STATISTICS = "statistics"; /** @see ProxoolDriver#getPropertyInfo */ public final String STATISTICS_PROPERTY = PROPERTY_PREFIX + STATISTICS; public static final String STATISTICS_LOG_LEVEL = "statistics-log-level"; /** @see ProxoolDriver#getPropertyInfo */ public final String STATISTICS_LOG_LEVEL_PROPERTY = PROPERTY_PREFIX + STATISTICS_LOG_LEVEL; public static final String JNDI_NAME = "jndi-name"; /** Prefix for generic JNDI properties. */ public static final String JNDI_PROPERTY_PREFIX = "jndi-"; /** @see ProxoolDriver#getPropertyInfo */ public final String JNDI_NAME_PROPERTY = PROPERTY_PREFIX + JNDI_NAME; // End JNDI public static final String STATISTICS_LOG_LEVEL_TRACE = "TRACE"; public static final String STATISTICS_LOG_LEVEL_DEBUG = "DEBUG"; public static final String STATISTICS_LOG_LEVEL_INFO = "INFO"; /** * Element name for the container of properties passed directlry to the delegate driver. */ public static final String DRIVER_PROPERTIES = "driver-properties"; /** * Configuration attribute used to indicate that a pool should be registered with JMX. */ public static final String JMX = "jmx"; /** * "proxool." prefixed version of {@link #JMX}. */ public final String JMX_PROPERTY = PROPERTY_PREFIX + JMX; /** * Configuration attribute for a list of jmx agent ids to register a * {@link org.logicalcobwebs.proxool.admin.jmx.ConnectionPoolMBean} to. * The list is comma separated. */ public static final String JMX_AGENT_ID = "jmx-agent-id"; /** * "proxool." prefixed version of {@link #JMX_AGENT_ID}. */ public final String JMX_AGENT_PROPERTY = PROPERTY_PREFIX + JMX_AGENT_ID; /** * Un-prefixed propety name for the Proxool alias configuration property. Value: alias */ public final String ALIAS = "alias"; /** * Un-prefixed propety name for the Proxool driver class configuration property. Value: driver-class */ public final String DRIVER_CLASS = "driver-class"; /** * Prefixed propety name for the Proxool driver class configuration property. Value: proxool.driver-class */ public final String DRIVER_CLASS_PROPERTY = PROPERTY_PREFIX + DRIVER_CLASS;; /** * Un-prefixed propety name for the Proxool driver url configuration property. Value: driver-url */ public final String DRIVER_URL = "driver-url"; /** * Prefixed propety name for the Proxool driver url configuration property. Value: proxool.driver-url */ public final String DRIVER_URL_PROPERTY = PROPERTY_PREFIX + DRIVER_URL; } /* Revision history: $Log: ProxoolConstants.java,v $ Revision 1.21 2004/06/02 20:39:17 billhorsman New injectable interface constants Revision 1.20 2004/03/15 02:43:47 chr32 Removed explicit JNDI properties. Going for a generic approach instead. Added constant for JNDI properties prefix. Revision 1.19 2003/09/30 18:39:08 billhorsman New test-before-use, test-after-use and fatal-sql-exception-wrapper-class properties. Revision 1.18 2003/09/29 17:48:21 billhorsman New fatal-sql-exception-wrapper-class allows you to define what exception is used as a wrapper. This means that you can make it a RuntimeException if you need to. Revision 1.17 2003/09/05 17:00:42 billhorsman New wrap-fatal-sql-exceptions property. Revision 1.16 2003/07/23 06:54:48 billhorsman draft JNDI changes (shouldn't effect normal operation) Revision 1.15 2003/03/05 23:28:56 billhorsman deprecated maximum-new-connections property in favour of more descriptive simultaneous-build-throttle Revision 1.14 2003/03/03 11:11:58 billhorsman fixed licence Revision 1.13 2003/02/26 16:05:52 billhorsman widespread changes caused by refactoring the way we update and redefine pool definitions. Revision 1.12 2003/02/24 18:02:24 chr32 Added JMX related constants. Revision 1.11 2003/02/24 01:16:15 chr32 Added constant for "driver-properties" property. Revision 1.10 2003/02/06 15:41:17 billhorsman add statistics-log-level Revision 1.9 2003/01/30 17:22:03 billhorsman new statistics property Revision 1.8 2003/01/23 10:41:05 billhorsman changed use of pool-name to alias for consistency Revision 1.7 2002/12/26 11:32:22 billhorsman Moved ALIAS, DRIVER_URL and DRIVER_CLASS constants from XMLConfgiurator to ProxoolConstants. Revision 1.6 2002/12/15 19:22:51 chr32 Added constant for proxool xml namespace. Revision 1.5 2002/12/11 01:47:12 billhorsman extracted property names without proxool. prefix for use by XMLConfigurators. Revision 1.4 2002/11/09 15:50:49 billhorsman new trace constant Revision 1.3 2002/10/27 13:29:38 billhorsman deprecated debug-level in favour of verbose Revision 1.2 2002/10/25 15:59:32 billhorsman made non-public where possible Revision 1.1.1.1 2002/09/13 08:13:06 billhorsman new Revision 1.3 2002/08/24 19:57:15 billhorsman checkstyle changes Revision 1.2 2002/07/12 23:03:22 billhorsman added doc headers Revision 1.7 2002/07/10 16:14:47 billhorsman widespread layout changes and move constants into ProxoolConstants Revision 1.6 2002/07/02 11:19:08 billhorsman layout code and imports Revision 1.5 2002/07/02 08:27:47 billhorsman bug fix when settiong definition, displayStatistics now available to ProxoolFacade, prototyper no longer attempts to make connections when maximum is reached Revision 1.4 2002/06/28 11:19:47 billhorsman improved doc */
解密接口类Decryptool.java
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.logicalcobwebs.proxool.util; /** * * @author zhappy */ public interface Decryptool { /** * 解密字符串 * @param content 密文 * @return 明文 */ public String decrypt(String content); }
PropertyConfigurator.java
/* * This software is released under a licence similar to the Apache Software Licence. * See org.logicalcobwebs.proxool.package.html for details. * The latest version is available at http://proxool.sourceforge.net */ package org.logicalcobwebs.proxool.configuration; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.logicalcobwebs.proxool.ProxoolConstants; import org.logicalcobwebs.proxool.ProxoolException; import org.logicalcobwebs.proxool.ProxoolFacade; import org.logicalcobwebs.proxool.util.Decryptool; /** * Uses a standard Java properties file to configure Proxool. For example: * * <pre> * jdbc-0.proxool.alias=property-test * jdbc-0.proxool.driver-url=jdbc:hsqldb:. * jdbc-0.proxool.driver-class=org.hsqldb.jdbcDriver * jdbc-0.encrypt=org.logicalcobwebs.proxool.util.Decryptool * jdbc-0.user=foo * jdbc-0.password=bar * jdbc-0.proxool.house-keeping-sleep-time=40000 * jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE * jdbc-0.proxool.maximum-connection-count=10 * jdbc-0.proxool.minimum-connection-count=3 * jdbc-0.proxool.maximum-connection-lifetime=18000000 * jdbc-0.proxool.simultaneous-build-throttle=5 * jdbc-0.proxool.recently-started-threshold=40000 * jdbc-0.proxool.overload-without-refusal-lifetime=50000 * jdbc-0.proxool.maximum-active-time=60000 * jdbc-0.proxool.verbose=true * jdbc-0.proxool.trace=true * jdbc-0.proxool.fatal-sql-exception=Fatal error * jdbc-0.proxool.prototype-count=2 * * jdbc-1.proxool.alias=property-test-2 * jdbc-1.proxool.driver-url=jdbc:hsqldb:. * jdbc-1.proxool.driver-class=org.hsqldb.jdbcDriver * jdbc-1.user=scott * jdbc-1.password=tiger * jdbc-1.proxool.house-keeping-sleep-time=40000 * jdbc-1.proxool.house-keeping-test-sql=select CURRENT_DATE * jdbc-1.proxool.maximum-connection-count=10 * jdbc-1.proxool.minimum-connection-count=3 * jdbc-1.proxool.maximum-connection-lifetime=18000000 * jdbc-1.proxool.simultaneous-build-throttle=5 * jdbc-1.proxool.recently-started-threshold=40000 * jdbc-1.proxool.overload-without-refusal-lifetime=50000 * jdbc-1.proxool.maximum-active-time=60000 * jdbc-1.proxool.verbose=true * jdbc-1.proxool.trace=true * jdbc-1.proxool.fatal-sql-exception=Fatal error * jdbc-1.proxool.prototype-count=2 * </pre> * * <p>The first word (up to the first dot) must start with "jdbc", but it can be * anything you like. Use unique names to identify each pool. Any property not * starting with "jdbc" will be ignored.</p> <p> The properties prefixed with * "proxool." will be used by Proxool while the properties that are not prefixed * will be passed on to the delegate JDBC driver. </p> * * @version $Revision: 1.11 $, $Date: 2006/01/18 14:39:58 $ * @author Bill Horsman ([email protected]) * @author $Author: billhorsman $ (current maintainer) * @since Proxool 0.5 */ public class PropertyConfigurator { private static final Log LOG = LogFactory.getLog(PropertyConfigurator.class); protected static final String PREFIX = "jdbc"; private static final String DOT = "."; private static final String EXAMPLE_FORMAT = PREFIX + "*" + DOT + "*"; /** * Configure proxool with the given properties file. * * @param filename the filename of the properties file. * @throws ProxoolException if the configuration fails. */ public static void configure(String filename) throws ProxoolException { Properties properties = new Properties(); try { properties.load(new FileInputStream(filename)); } catch (IOException e) { throw new ProxoolException("Couldn't load property file " + filename); } configure(properties); } /** * Configure proxool with the given properties. * * @param properties the properties instance to use. * @throws ProxoolException if the configuration fails. */ public static void configure(Properties properties) throws ProxoolException { final Map propertiesMap = new HashMap(); final Iterator allPropertyKeysIterator = properties.keySet().iterator(); Properties proxoolProperties = null; while (allPropertyKeysIterator.hasNext()) { String key = (String) allPropertyKeysIterator.next(); String value = properties.getProperty(key); if (key.startsWith(PREFIX)) { int a = key.indexOf(DOT); if (a == -1) { throw new ProxoolException("Property " + key + " must be of the format " + EXAMPLE_FORMAT); } final String tag = key.substring(0, a); final String name = key.substring(a + 1); proxoolProperties = (Properties) propertiesMap.get(tag); if (proxoolProperties == null) { proxoolProperties = new Properties(); propertiesMap.put(tag, proxoolProperties); } proxoolProperties.put(name, value); } } final Iterator tags = propertiesMap.keySet().iterator(); while (tags.hasNext()) { proxoolProperties = (Properties) propertiesMap.get(tags.next()); final String ec = proxoolProperties.getProperty(ProxoolConstants.USER_PASSWORD_ENCRYPT); if (ec != null) {//如果在配置文件中存在解密项就先动态加载解密类,然后对用户名和密码进行解密 Decryptool dec = null; try { Class c = Class.forName(ec); Object o = c.newInstance(); dec = (Decryptool) o; } catch (Exception e) { LOG.error("new Class [" + ec + "] fail!", e); } final String user = proxoolProperties.getProperty(ProxoolConstants.USER_PROPERTY);//取原值 proxoolProperties.setProperty(ProxoolConstants.USER_PROPERTY, dec.decrypt(user));//解密并设置 final String password = proxoolProperties.getProperty(ProxoolConstants.PASSWORD_PROPERTY);//取原值 proxoolProperties.setProperty(ProxoolConstants.PASSWORD_PROPERTY, dec.decrypt(password));//解密并设置 } // make sure that required propeties are defined // and build the url // Check that we have defined the minimum information final String driverClass = proxoolProperties.getProperty(ProxoolConstants.DRIVER_CLASS_PROPERTY); final String driverUrl = proxoolProperties.getProperty(ProxoolConstants.DRIVER_URL_PROPERTY); if (driverClass == null || driverUrl == null) { throw new ProxoolException("You must define the " + ProxoolConstants.DRIVER_CLASS_PROPERTY + " and the " + ProxoolConstants.DRIVER_URL_PROPERTY + "."); } final String alias = proxoolProperties.getProperty(ProxoolConstants.ALIAS_PROPERTY); // Build the URL; optionally defining a name StringBuffer url = new StringBuffer(); url.append("proxool"); if (alias != null) { url.append(ProxoolConstants.ALIAS_DELIMITER); url.append(alias); proxoolProperties.remove(ProxoolConstants.ALIAS_PROPERTY); } url.append(ProxoolConstants.URL_DELIMITER); url.append(driverClass); proxoolProperties.remove(ProxoolConstants.DRIVER_CLASS_PROPERTY); url.append(ProxoolConstants.URL_DELIMITER); url.append(driverUrl); proxoolProperties.remove(ProxoolConstants.DRIVER_URL_PROPERTY); if (LOG.isDebugEnabled()) { LOG.debug("Created url: " + url); } ProxoolFacade.registerConnectionPool(url.toString(), proxoolProperties); } } } /* * Revision history: $Log: PropertyConfigurator.java,v $ Revision 1.11 * 2006/01/18 14:39:58 billhorsman Unbundled Jakarta's Commons Logging. * * Revision 1.10 2003/03/05 23:28:56 billhorsman deprecated * maximum-new-connections property in favour of more descriptive * simultaneous-build-throttle * * Revision 1.9 2003/03/03 11:12:00 billhorsman fixed licence * * Revision 1.8 2003/02/06 17:41:05 billhorsman now uses imported logging * * Revision 1.7 2003/02/05 14:46:31 billhorsman fixed copyright and made PREFIX * protected for use by ServletConfigurator * * Revision 1.6 2003/01/27 18:26:43 billhorsman refactoring of ProxyConnection * and ProxyStatement to make it easier to write JDK 1.2 patch * * Revision 1.5 2003/01/23 10:41:05 billhorsman changed use of pool-name to * alias for consistency * * Revision 1.4 2003/01/22 17:35:01 billhorsman checkstyle * * Revision 1.3 2003/01/18 15:13:12 billhorsman Signature changes (new * ProxoolException thrown) on the ProxoolFacade API. * * Revision 1.2 2002/12/26 11:32:59 billhorsman Rewrote to support new format. * * Revision 1.1 2002/12/15 18:48:33 chr32 Movied in from 'ext' source tree. * * Revision 1.4 2002/11/09 15:57:57 billhorsman fix doc * * Revision 1.3 2002/11/02 14:22:16 billhorsman Documentation * * Revision 1.2 2002/10/27 13:05:01 billhorsman checkstyle * * Revision 1.1 2002/10/27 12:00:16 billhorsman moved classes from ext * sub-package which is now obsolete - let's keep everything together in one * place * * Revision 1.1 2002/10/25 10:40:27 billhorsman draft * */
XMLConfigurator.java
/* * This software is released under a licence similar to the Apache Software Licence. * See org.logicalcobwebs.proxool.package.html for details. * The latest version is available at http://proxool.sourceforge.net */ package org.logicalcobwebs.proxool.configuration; import java.util.Iterator; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.logicalcobwebs.proxool.ProxoolConstants; import org.logicalcobwebs.proxool.ProxoolException; import org.logicalcobwebs.proxool.ProxoolFacade; import org.logicalcobwebs.proxool.util.Decryptool; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; /** * <p>A SAX 2 ContentHandler that can configure Proxool from an XML source.</p> * * <p>This is just a <a * href="http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html" * target="_new" >ContentHandler</a>, so you must associate it with a SAX parser * for it to actually do anything. If you have JAXP available {@link JAXPConfigurator} * will do this for you.</p> * * <p>Properties that you pass on to the delegate driver have to be treated * specially. They must be contained within a <driver-properties> * element.</p> * * <p>See the <a href="The latest version is available at * http://proxool.sourceforge.net/properties.html" target="_new">Proxool * properties</a> for documentation on the available configuration * properties.</p> * * Example configuration: * <pre> * <proxool> * <alias>apple</alias> * <encrypt>org.logicalcobwebs.proxool.util.Decryptool</alias> * <driver-url>jdbc:hsqldb:.</driver-url> * <driver-class>org.hsqldb.jdbcDriver</driver-class> * <driver-properties> * <property name="user" value="abc" /> * <property name="password" value="def" /> * </driver-properties> * <house-keeping-sleep-time>40000</house-keeping-sleep-time> * <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql> * <maximum-connection-count>10</maximum-connection-count> * <minimum-connection-count>3</minimum-connection-count> * <maximum-connection-lifetime>18000000</maximum-connection-lifetime> <!-- 5 hours --> * <simultaneous-build-throttle>5</simultaneous-build-throttle> * <recently-started-threshold>40000</recently-started-threshold> * <overload-without-refusal-lifetime>50000</overload-without-refusal-lifetime> * <maximum-active-time>60000</maximum-active-time> * <verbose>true</verbose> * <trace>true</trace> * <fatal-sql-exception>ORA-1234</fatal-sql-exception> * <prototype-count>2</prototype-count> * </proxool> * </pre> * * When the parser reaches the end of the <proxool> element the pool is * automatically registered. You can contain the <proxool> element in any * other elements as you wish. And the <proxool> element can occur as many * times as you wish. This allows you to use an XML file that configures your * whole application as the source. This configurator will ignore everything * apart from the elements contained within the <proxool> element. <p><a * name="#validation"> <b>Validation</b><br> A couple of additional steps are * required if you want your SAX parser to validate your Proxool xml * confguration: <ul> <li> Put your proxool configuration elements inside a root * <code>proxool-config</code> element. The document must adhere to the <a * href="proxool.dtd">Proxool dtd</a>. </li> <li> Add a * <code>DOCTYPE</code> entry to your xml with a system id containing the * <i>absolute url</i> to the Proxool dtd. The Proxool jar contains a copy of * the Proxool dtd in the confguration package. You can reference that with a * jar url like this:<br> * <code><nobr><!DOCTYPE proxool-config SYSTEM "jar:file:///C:/Proxool/lib/proxool.jar!/org/logicalcobwebs/proxool/configuration/proxool.dtd"></nobr></code></li> * <li> Configure your parser to be validating. In the {@link JAXPConfigurator} * this is done by passing * <code>true</code> as the second arghument to any of the * <code>configure</code> methods. </li> </ul> </p> <p>This class is not thread * safe.</p> * * @version $Revision: 1.18 $, $Date: 2006/01/18 14:39:58 $ * @author billhorsman * @author $Author: billhorsman $ (current maintainer) */ public class XMLConfigurator extends DefaultHandler { private static final Log LOG = LogFactory.getLog(XMLConfigurator.class); private StringBuffer content = new StringBuffer(); private String poolName; private String driverClass; private String driverUrl; private Properties properties = new Properties(); private static final String PROXOOL = "proxool"; private static final String DRIVER_PROPERTIES = "driver-properties"; private static final String PROPERTY = "property"; private static final String NAME = "name"; private static final String VALUE = "value"; private boolean insideDelegateProperties; private boolean insideProxool; /** * @see org.xml.sax.ContentHandler#startElement */ @Override public void startElement(String uri, String lname, String qname, Attributes attributes) throws SAXException { content.setLength(0); if (!namespaceOk(uri)) { return; } final String elementName = getElementName(uri, lname, qname); if (elementName.equals(PROXOOL)) { if (insideProxool) { throw new SAXException("A <" + PROXOOL + "> element can't contain another <" + PROXOOL + "> element."); } insideProxool = true; properties.clear(); driverClass = null; driverUrl = null; } if (insideProxool) { if (elementName.equals(DRIVER_PROPERTIES)) { insideDelegateProperties = true; } else if (insideDelegateProperties) { if (elementName.equals(PROPERTY)) { setDriverProperty(attributes); } } } } /** * @see org.xml.sax.ContentHandler#characters */ @Override public void characters(char[] chars, int start, int length) throws SAXException { if (insideProxool) { content.append(chars, start, length); } } /** * @see org.xml.sax.ContentHandler#endElement */ @Override public void endElement(String uri, String lname, String qname) throws SAXException { if (!namespaceOk(uri)) { return; } final String elementName = getElementName(uri, lname, qname); // Are we ending a proxool configuration section? if (elementName.equals(PROXOOL)) { // Check that we have defined the minimum information if (driverClass == null || driverUrl == null) { throw new SAXException("You must define the " + ProxoolConstants.DRIVER_CLASS + " and the " + ProxoolConstants.DRIVER_URL + "."); } // Build the URL; optinally defining a name StringBuffer url = new StringBuffer(); url.append("proxool"); if (poolName != null) { url.append(ProxoolConstants.ALIAS_DELIMITER); url.append(poolName); } url.append(ProxoolConstants.URL_DELIMITER); url.append(driverClass); url.append(ProxoolConstants.URL_DELIMITER); url.append(driverUrl); if (LOG.isDebugEnabled()) { LOG.debug("Created url: " + url); } // Register the pool try { final String ec = properties.getProperty(ProxoolConstants.PROPERTY_PREFIX + ProxoolConstants.USER_PASSWORD_ENCRYPT); if (ec != null) {//判断配置文件中是否有解密class的配置,如果有则动态加载 Decryptool dec = null; try { Class c = Class.forName(ec); Object o = c.newInstance(); dec = (Decryptool) o; } catch (Exception e) { LOG.error("new Class [" + ec + "] fail!", e); } final String user = properties.getProperty(ProxoolConstants.USER_PROPERTY);//取原值 properties.setProperty(ProxoolConstants.USER_PROPERTY, dec.decrypt(user));//解密并设置 final String password = properties.getProperty(ProxoolConstants.PASSWORD_PROPERTY);//取原值 properties.setProperty(ProxoolConstants.PASSWORD_PROPERTY, dec.decrypt(password));//解密并设置 } ProxoolFacade.registerConnectionPool(url.toString(), properties); } catch (ProxoolException e) { throw new SAXException(e); } // This ensures we ignore remaining XML until we come across another // <proxool> element. insideProxool = false; } if (insideProxool && !elementName.equals(PROXOOL)) { if (elementName.equals(DRIVER_PROPERTIES)) { insideDelegateProperties = false; } else if (!insideDelegateProperties) { setProxoolProperty(elementName, content.toString().trim()); } } } private void setProxoolProperty(String localName, String value) { if (localName.equals(ProxoolConstants.ALIAS)) { poolName = value; } else if (localName.equals(ProxoolConstants.DRIVER_CLASS)) { driverClass = value; } else if (localName.equals(ProxoolConstants.DRIVER_URL)) { driverUrl = value; } else { if (LOG.isDebugEnabled()) { LOG.debug("Setting property '" + ProxoolConstants.PROPERTY_PREFIX + localName + "' to value '" + value + "'."); } properties.put(ProxoolConstants.PROPERTY_PREFIX + localName, value); } } private void setDriverProperty(Attributes attributes) throws SAXException { final String name = attributes.getValue(NAME); final String value = attributes.getValue(VALUE); if (name == null || name.length() < 1 || value == null) { throw new SAXException("Name or value attribute missing from property element." + "Name: '" + name + "' Value: '" + value + "'."); } if (LOG.isDebugEnabled()) { if (name.toLowerCase().indexOf("password") > -1) { LOG.debug("Adding driver property: " + name + "=" + "*******"); } else { LOG.debug("Adding driver property: " + name + "=" + value); } } properties.put(name, value); } /** * @see org.xml.sax.ErrorHandler#warning(SAXParseException) */ @Override public void warning(SAXParseException e) throws SAXException { // Just debug-log the warning. We'll probably survive. LOG.debug("The saxparser reported a warning.", e); } /** * @see org.xml.sax.ErrorHandler#error(SAXParseException) */ @Override public void error(SAXParseException e) throws SAXException { // On error we rethrow the exception. // This should cause the parser stop and an exeption be thrown back to the client. throw e; } /** * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException) */ @Override public void fatalError(SAXParseException e) throws SAXException { // On fatal error we rethrow the exception. // This should cause the parser stop and an exeption be thrown back to the client. throw e; } // If no namespace use qname, else use lname. private String getElementName(String uri, String lname, String qname) { if (uri == null || "".equals(uri)) { return qname; } else { return lname; } } private boolean namespaceOk(String uri) { return uri == null || uri.length() == 0 || uri.equals(ProxoolConstants.PROXOOL_XML_NAMESPACE_URI); } }
把上面这几个类编译后,添加、替换原包中的类就可以了。使用上跟原来没有区别。
注意:如果配置使用了解密,就必须先实现接口Decryptool,并在配置文件中设置正确的类路径
接口Decryptool的简单实现:
DecUtil.java
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package cn.bq.tools; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.logicalcobwebs.proxool.util.Decryptool; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * * @author zhappy */ public class DecUtil implements Decryptool { @Override public String decrypt(String string) { BASE64Decoder decode = new BASE64Decoder(); String s = null; try { byte[] b = decode.decodeBuffer(string); s = new String(b); } catch (IOException ex) { Logger.getLogger(DecUtil.class.getName()).log(Level.SEVERE, null, ex); } return s; } public String encrypt(String string) { BASE64Encoder encode = new BASE64Encoder(); return encode.encode(string.getBytes()); } public static void main(String[] args) { DecUtil dec = new DecUtil(); String str = "password"; System.out.println("未加密前:" + str); String _str = dec.encrypt(str); System.out.println("加密后:" + _str); System.out.println("加密字符串[" + _str + "]解密后:" + dec.decrypt(_str)); } }
xml配置文件的
JAXPConfigurator.configure("src/java-test/org/logicalcobwebs/proxool/configuration/test-no-ns.xml", false); …… connection = DriverManager.getConnection("proxool.xml-test");
properties 配置文件的
PropertyConfigurator.configure("src/java-test/org/logicalcobwebs/proxool/configuration/test.properties"); …… connection = DriverManager.getConnection("proxool.property-test");