在扩展的 BasicDataSource 对象上使用 JNDI
Posted
技术标签:
【中文标题】在扩展的 BasicDataSource 对象上使用 JNDI【英文标题】:Using JNDI on an extended BasicDataSource object 【发布时间】:2013-06-10 18:57:01 【问题描述】:我想使用 jndi 在我的 jdbc 连接上实现连接池,但我也想使用扩展的 BasicDataSource 对象。我对使用 tomcat 5.5 有限制。要求是对 jndi 上下文资源属性中提供的密码进行加解密。
我正在尝试实现与这篇文章类似的东西 Link
这是我的 servlet,无需扩展 BasicDataSource 即可完美运行。
public class ReturnBlobOld extends HttpServlet
private static final long serialVersionUID = 1L;
private org.apache.tomcat.dbcp.dbcp.BasicDataSource ds = null;
// this is my extended DS which is not working
//private custompages.NewBasicDataSource ds = null;
public void init(ServletConfig config) throws ServletException
super.init(config);
getDataSource();
public void getDataSource()
Context ctxt = null;
try
ctxt = new InitialContext();
ds = (BasicDataSource) ctxt.lookup("java:comp/env/jdbc/mysql");
//ds = (NewBasicDataSource) ctxt.lookup("java:comp/env/jdbc/mysql");
ctxt.close();
catch (NamingException e)
e.printStackTrace();
public void doGet(....)
........
Connection connection = null;
Statement statement = null;
ResultSet res = null;
try
connection = ds.getConnection();
statement = connection.createStatement();
................
这是我扩展的 BasicDataSource 类
package custompages;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
public class NewBasicDataSource extends BasicDataSource
protected synchronized DataSource createDataSource() throws SQLException
String decryptedPassword = decryptPassword( super.getPassword() );
super.setPassword( decryptedPassword );
return super.createDataSource();
private String decryptPassword( String password )
return "abcdef";//logic to decrypt current password
这是我的 context.xml 文件
<context>
<Resource name="jdbc/mysql"
auth="Container"
type="javax.sql.DataSource"
username="root"
password="abcdef"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.2.2:3306/world"
maxActive="1"
maxIdle="1"
maxWait="5000"
timeBetweenEvictionRunsMillis="5000"
minEvictableIdleTimeMillis="100"
removeAbandoned="true"
removeAbandonedTimeout="3"/>
</context>
这是我的 WEB-INF 资源声明
<resource-ref>
<res-ref-name>jdbc/mysql</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
我的 servlet 运行良好,我可以使用上面的代码初始化 jdbc 池。但是当我尝试使用我的扩展类来加密-解密密码时,我得到如下异常。
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource
custompages.ReturnBlobOld.getDataSource(ReturnBlobOld.java:39)
custompages.ReturnBlobOld.init(ReturnBlobOld.java:32)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:881)
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:674)
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:541)
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
java.lang.Thread.run(Thread.java:595)
请建议扩展此类以与 jndi 一起使用的正确方法
【问题讨论】:
【参考方案1】:好的, 这是我现在正在做的替代方案。我已经删除了 JNDI 资源并直接在我的 servlet 中创建了一个新的 BasicDataSource 对象,而不是从 JNDI 工厂方法调用中生成它。为了自定义,我可以使用属性文件参数化属性吗?
public void getDataSource()
ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("abcde");
ds.setUrl("jdbc:mysql://192.168.2.2:3306/world");
ds.setMaxActive(8);
ds.setMaxIdle(8);
ds.setMaxWait(10000);
ds.setTimeBetweenEvictionRunsMillis(300000);
ds.setMinEvictableIdleTimeMillis(1800000);
ds.setRemoveAbandonedTimeout(300);
ds.setRemoveAbandoned(true);
【讨论】:
以上是关于在扩展的 BasicDataSource 对象上使用 JNDI的主要内容,如果未能解决你的问题,请参考以下文章
对于org.apache.commons.dbcp.BasicDataSource的配置认知
BasicDatasource 和 PoolingDatasource 的区别