好的,我在server.xml中的Tomcat 5.5中有一个资源用于数据库连接,如下所示:
<Resource name="jdbc/MyApp" auth="Container" type="com.mchange.v2.c3p0.ComboPooledDataSource" driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" maxPoolSize="100" minPoolSize="5"
acquireIncrement="5"
user="username"
password="password"
factory="org.apache.naming.factory.BeanFactory"
jdbcUrl="jdbc:sqlserver://localhost:1433;databaseName=myDatabase;autoReconnect=true" />
有没有人试图扩展上面的ComboPooledDataSource?问题是数据库密码是明文。想法是首先加密密码并将加密密钥放在server.xml中。我有一个解密实用程序,所以我可以在尝试连接数据库之前解密密钥。
我为org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory的问题找到了一个示例解决方案,但我没有使用此连接池。我正在使用C3P0。之前有人用C3P0试过吗?
答案 0 :(得分:1)
是的,您无法扩展com.mchange.v2.c3p0.ComboPooledDataSource
,因为它是公开的。这是我实现这一目标的解决方法。
我已扩展org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
并将com.mchange.v2.c3p0.ComboPooledDataSource
数据源作为构造函数参数传递。
以下是我上述数据源的hibernate.cfg.xml
配置:
<bean id="dataSource" class="MyDataSource">
<constructor-arg ref="c3p0DataSource" />
</bean>
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driver.className}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="acquireIncrement" value="${dataSource.acquireIncrement}" />
<property name="acquireRetryAttempts" value="${dataSource.acquireRetryAttempts}" />
<property name="acquireRetryDelay" value="${dataSource.acquireRetryDelay}" />
<property name="autoCommitOnClose" value="${dataSource.autoCommitOnClose}" />
<property name="breakAfterAcquireFailure" value="${dataSource.breakAfterAcquireFailure}" />
<property name="checkoutTimeout" value="${dataSource.checkoutTimeout}" />
<property name="debugUnreturnedConnectionStackTraces"
value="${dataSource.debugUnreturnedConnectionStackTraces}" />
<property name="forceIgnoreUnresolvedTransactions"
value="${dataSource.forceIgnoreUnresolvedTransactions}" />
<property name="idleConnectionTestPeriod" value="${dataSource.idleConnectionTestPeriod}" />
<property name="initialPoolSize" value="${dataSource.initialPoolSize}" />
<property name="maxAdministrativeTaskTime" value="${dataSource.maxAdministrativeTaskTime}" />
<property name="maxConnectionAge" value="${dataSource.maxConnectionAge}" />
<property name="maxIdleTime" value="${dataSource.maxIdleTime}" />
<property name="maxIdleTimeExcessConnections" value="${dataSource.maxIdleTimeExcessConnections}" />
<property name="maxPoolSize" value="${dataSource.maxPoolSize}" />
<property name="maxStatements" value="${dataSource.maxStatements}" />
<property name="maxStatementsPerConnection" value="${dataSource.maxStatementsPerConnection}" />
<property name="minPoolSize" value="${dataSource.minPoolSize}" />
<property name="numHelperThreads" value="${dataSource.numHelperThreads}" />
<property name="propertyCycle" value="${dataSource.propertyCycle}" />
<property name="testConnectionOnCheckin" value="${dataSource.testConnectionOnCheckin}" />
<property name="testConnectionOnCheckout" value="${dataSource.testConnectionOnCheckout}" />
<property name="unreturnedConnectionTimeout" value="${dataSource.unreturnedConnectionTimeout}" />
</bean>
Mine jdbc.properties file:
jdbc.driver.className=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=xxxxx
jdbc.username=xxx
jdbc.password=xxxxxxxxx #Encrytped password here
jdbc.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update
dataSource.acquireIncrement=3
dataSource.acquireRetryAttempts=30
dataSource.acquireRetryDelay=60000
dataSource.autoCommitOnClose=false
dataSource.breakAfterAcquireFailure=false
dataSource.checkoutTimeout=0
dataSource.debugUnreturnedConnectionStackTraces=false
dataSource.forceIgnoreUnresolvedTransactions=false
dataSource.idleConnectionTestPeriod=0
dataSource.initialPoolSize=10
dataSource.maxAdministrativeTaskTime=0
dataSource.maxConnectionAge=0
dataSource.maxIdleTime=0
dataSource.maxIdleTimeExcessConnections=0
dataSource.maxPoolSize=10
dataSource.maxStatements=0
dataSource.maxStatementsPerConnection=0
dataSource.minPoolSize=10
dataSource.numHelperThreads=3
dataSource.propertyCycle=0
dataSource.testConnectionOnCheckin=false
dataSource.testConnectionOnCheckout=false
dataSource.unreturnedConnectionTimeout=0
Mine extended class where I decrypt the password before passing the datasource to transaction Proxy wrapper.
import javax.sql.DataSource;
import org.jasypt.util.text.BasicTextEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import com.csc.emms.common.EMMSConstraints;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class MyDataSource extends TransactionAwareDataSourceProxy
{
private static char[] appName =
{
'B', 'I', 'N', 'G', 'O', 'D', 'I', 'N', 'G', 'O'
};
@Autowired
// Inject your class by constructor
MyDataSource(ComboPooledDataSource dataSource)
{
super.setTargetDataSource(decryptPassword(dataSource));
}
private DataSource decryptPassword(ComboPooledDataSource dataSource)
{
dataSource.setPassword(decode(dataSource.getPassword()));
return dataSource;
}
private String decode(String encodedPassword)
{
BasicTextEncryptor decoder = new BasicTextEncryptor();
decoder.setPasswordCharArray(appName);
return decoder.decrypt(encodedPassword);
}
private String encode(String password)
{
BasicTextEncryptor encoder = new BasicTextEncryptor();
encoder.setPasswordCharArray(appName);
return encoder.encrypt(password);
}
}
Hope this resolved your issue.
答案 1 :(得分:0)
答案 2 :(得分:0)
自com.mchange.v2.c3p0.ComboPooledDataSource
以来
公共最终类,您无法扩展它。
答案 3 :(得分:0)
您无法扩展ComboPooledDataSource
,但您可以通过扩展其父类AbstractComboPooledDataSource
来基本复制它。您可以通过获取source from Github或通过反编译类文件来真正地,真正地接近复制它。结果将如下所示:
import com.mchange.v2.c3p0.AbstractComboPooledDataSource;
public final class YourC3p0DataSource extends AbstractComboPooledDataSource
implements Serializable, Referenceable {
public void setPassword(String encryptedPassword) {
try {
String decryptedPassword
= yourDecryption(encryptedPassword);
super.setPassword(decryptedPassword);
} catch (Exception e) { /* ... */ }
}
/* Increment a few other methods found in ComboPooledDataSource. */
}