|
|
| 在Web应用中使用XML文件配置数据源 |
作者:
文章来源:
访问次数:656次
加入时间:2007年04月22日
|
|
在web应用中使用XML配置数据源,我们一般要通过以下几步来实现: (一) 编写配置数据源的XML文件 本例中的配置文件存放在/WEB-INF/目录下,也可以放在别的目录下,只是在操作的时候不同罢了。 (1) MS SQL 的配置文件/WEB-INF/mssql.xml,内容如下: <?xml version="1.0" encoding="UTF-8"?> <DataSource> <!-- configure the datasource of MSSQL --> <DatabaseUser>sa</DatabaseUser> <DatabasePassword>jckjdkmcj</DatabasePassword> <DatabaseName>northwind</DatabaseName> <ServerName>10.0.0.168</ServerName> <ServerPort>1433</ServerPort> <MaxConnections>100</MaxConnections> </DataSource> (2) Oracle的配置文件/WEB-INF/oracle.xml,内容如下: <?xml version="1.0" encoding="UTF-8"?> <DataSource> <!-- configure the datasource of MSSQL --> <DatabaseUser>zhangyi</DatabaseUser> <DatabasePassword>jckjdkmcj</DatabasePassword> <DatabaseName>zydb</DatabaseName> <ServerName>10.0.0.168</ServerName> <ServerPort>1521</ServerPort> <MaxConnections>100</MaxConnections> </DataSource> 注意:此处两个文件的格式是一样的,因为在下面的解析的过程中我们用到了是用的同一个接口 (二) 设计解析XML文件的一个接口 在此,我们用定义了一个接口:config.java /* * Created on 2005-8-29 * * the supper class for parse the xml files * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package zy.pro.wd.xml;
import java.io.InputStream; import javax.xml.parsers.*; import javax.servlet.ServletContext; import org.xml.sax.InputSource; import org.w3c.dom.*;
/** * @author zhangyi * * TODO To change the template for this generated type comment go to Window - * Preferences - Java - Code Style - Code Templates */ public abstract class Config { /** * the supper class for parse the xml files */ protected Element root;
protected void init(ServletContext sctx, String xmlFile) throws Exception { InputStream is=null; try{ is=sctx.getResourceAsStream(xmlFile); DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=factory.newDocumentBuilder(); Document doc=builder.parse(new InputSource(is)); root=doc.getDocumentElement(); System.out.println("root: "+root ); }catch(Exception e){ e.printStackTrace(); }finally{ if(is!=null){ is.close(); } } } protected String getElementText(Element parent,String name){ NodeList nodeList=parent.getElementsByTagName(name); if(nodeList.getLength()==0){ return null; } Element element=(Element)nodeList.item(0); StringBuffer sb=new StringBuffer(); for(Node child=element.getFirstChild();child!=null;child=child.getNextSibling()){ if(child.getNodeType()==Node.TEXT_NODE){ sb.append(child.getNodeValue()); } } return sb.toString().trim(); } protected void cleanup(){ root=null; } } (三) 定义解析我们自定义配置文件(XML文件)的 抽象类,此处我们定义了DataSourceConfig.java,文件内容如下: /* * Created on 2005-8-29 * *reading the JDBC datasource properties from xml files * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package zy.pro.wd.xml;
import javax.sql.DataSource; import javax.servlet.ServletContext;
/** * @author zhangyi * * TODO To change the template for this generated type comment go to Window - * Preferences - Java - Code Style - Code Templates */ public abstract class DataSourceConfig extends Config { private static final String DATABASE_USER = "DatabaseUser";
private static final String DATABASE_PASSWORD = "DatabasePassword";
private static final String SERVER_NAME = "ServerName";
private static final String DATABASE_NAME = "DatabaseName";
private static final String SERVER_PORT = "ServerPort"; protected DataSource ds; protected String databaseUser; protected String databasePassword; protected String serverName; protected String portNumber; protected String databaseName; public void init(ServletContext sctx,String xmlFile) throws Exception{ super.init(sctx,xmlFile); databaseUser=this.getElementText(root,DATABASE_USER); System.out.println("<br>databaseUser: "+databaseUser); databasePassword=this.getElementText(root,DATABASE_PASSWORD); System.out.println("<br>databasePassword: "+databasePassword); databaseName=this.getElementText(root,DATABASE_NAME); System.out.println("<br>databaseName: "+databaseName); serverName=this.getElementText(root,SERVER_NAME); System.out.println("<br>serverName: "+serverName); portNumber=this.getElementText(root,SERVER_PORT); System.out.println("<br>portNumber: "+portNumber); } public DataSource getDataSource(){ return ds; } } (四) 定义我们解析数据源配置文件的实现类 (1) 定义解析MS SQL 数据源的实现类MSSQLConfig.java.内容如下: /* * Created on 2005-8-31 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package zy.pro.wd.xml;
import javax.servlet.ServletContext;
import org.apache.commons.dbcp.BasicDataSource; import com.microsoft.jdbc.base.BaseConnectionPool;
/** * @author zhangyi * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class MSSQLConfig extends DataSourceConfig { private static final String MAX_CONNECTIONS = "MaxConnections";
public void init(ServletContext ctx, String xmlFile) throws Exception { super.init(ctx, xmlFile); String databaseURL = "jdbc:microsoft:sqlserver://" + this.serverName + ":" + this.portNumber + ";databaseName=" + this.databaseName; System.out.println("<br> databaseURL : " + databaseURL); ds = new BasicDataSource(); /* *此处使用的是apache 给提供的DBCP数据源 */ System.out.println("<br>ds: " + ds); ((BasicDataSource) ds).setUrl(databaseURL); ((BasicDataSource) ds).setUsername(this.databaseUser); ((BasicDataSource) ds).setPassword(this.databasePassword);
try { int maxConnections = Integer.parseInt(this.getElementText(root, MAX_CONNECTIONS)); ((BasicDataSource) ds).setMaxActive(maxConnections); } catch (Exception e) { e.printStackTrace(); } this.cleanup();
} } (2) 定义实现解析oracle数据源的实现类OracleConfig.java,内容如下: /* * Created on 2005-8-29 * *parse the xml file of the oracle configure * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package zy.pro.wd.xml;
import javax.sql.DataSource; import javax.servlet.ServletContext; import oracle.jdbc.pool.OracleConnectionCacheImpl;
/** * @author zhangyi * * TODO To change the template for this generated type comment go to Window - * Preferences - Java - Code Style - Code Templates */ public class OracleConfig extends DataSourceConfig {
private static final String MAX_CONNECTIONS = "MaxConnections";
public void init(ServletContext ctx, String xmlFile) throws Exception { super.init(ctx, xmlFile); String databaseURL = "jdbc:oracle:thin:@" + this.serverName + ":" + this.portNumber + ":" + this.databaseName; System.out.println("<br> databaseURL : " + databaseURL); /* *此处使用的Oracle给提供的数据源,也可以使用DBCP数据源 */ ds = new OracleConnectionCacheImpl(); System.out.println("<br>ds: " + ds); ((OracleConnectionCacheImpl) ds).setURL(databaseURL); ((OracleConnectionCacheImpl) ds).setUser(this.databaseUser); ((OracleConnectionCacheImpl) ds).setPassword(this.databasePassword);
try { int maxConnections = Integer.parseInt(this.getElementText(root, MAX_CONNECTIONS)); ((OracleConnectionCacheImpl) ds).setMaxLimit(maxConnections); } catch (Exception e) { e.printStackTrace(); } this.cleanup();
}
} (五) 编写Context的侦听器 (1) 编写MSSQL 数据源的侦听器类:MSSQLDataSourceListener.java,内容如下: /* * Created on 2005-8-30 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package zy.pro.wd.listener;
import javax.servlet.ServletContext; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import javax.naming.*; import zy.pro.wd.xml.*;
/** * @author zhangyi * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class MSSQLDataSourceListener implements ServletContextListener { /* * this is a listener class for mssql datasource registing in the web.xml */ public static String JNDI_NAME; private ServletContext sctx; public void contextInitialized(ServletContextEvent event){ sctx=event.getServletContext(); System.out.println("<br>sctx in listener : "+sctx); try{ Class cls=Class.forName(sctx.getInitParameter("MSSQLDataSourceConfig")); MSSQLConfig cfig=(MSSQLConfig)cls.newInstance(); System.out.println("<br>MSSQLConfig: "+cfig); cfig.init(sctx,sctx.getInitParameter("MSSQLDataSourceConfigXML")); InitialContext ctx=new InitialContext(); JNDI_NAME=sctx.getInitParameter("MSSQLDataSourceConfig"); System.out.println("MS SQL SERVER JNSI_NAME: "+JNDI_NAME); ctx.bind(JNDI_NAME,cfig.getDataSource()); }catch(Exception e){ sctx.log("MSSQLDataSourceListener",e); e.printStackTrace(); } } /* (non-Javadoc) * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) */ public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub sctx=null; } } (2) 编写Oracle的Context侦听器类OracleDataSourceListener.java,代码如下: /* * Created on 2005-8-30 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package zy.pro.wd.listener;
import javax.servlet.ServletContext; import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; import javax.naming.*; import zy.pro.wd.xml.*;
/** * @author zhangyi * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class OracleDataSourceListener implements ServletContextListener {
public static String JNDI_NAME; private ServletContext sctx; public void contextInitialized(ServletContextEvent event){ sctx=event.getServletContext(); System.out.println("<br>sctx in listener : "+sctx); try{ Class cls=Class.forName(sctx.getInitParameter("OracleDataSourceConfig")); OracleConfig cfig=(OracleConfig)cls.newInstance(); System.out.println("<br>OracleConfig: "+cfig); cfig.init(sctx,sctx.getInitParameter("OracleDataSourceConfigXML")); InitialContext ctx=new InitialContext(); JNDI_NAME=sctx.getInitParameter("OracleDataSourceConfig"); System.out.println("oracle DataSouce JNDI_NAME: "+JNDI_NAME); ctx.bind(JNDI_NAME,cfig.getDataSource()); }catch(Exception e){ sctx.log("DataSourceListener",e); e.printStackTrace(); } } /* (non-Javadoc) * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) */ public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub sctx=null; } }
(六) 在Web.xml中配置数据源,配置代码如下:
<!-- configure the oracle datasource by XML files --> <context-param> <param-name>OracleDataSourceConfigXML</param-name> <param-value>/WEB-INF/oracle.xml</param-value> </context-param> <context-param> <param-name>OracleDataSourceConfig</param-name> <param-value>zy.pro.wd.xml.OracleConfig</param-value> </context-param> <listener> <listener-class>zy.pro.wd.listener.OracleDataSourceListener</listener-class> </listener> <!-- configure the MSSQL datasource using XML files --> <context-param> <param-name>MSSQLDataSourceConfigXML</param-name> <param-value>/WEB-INF/mssql.xml</param-value> </context-param> <context-param> <param-name>MSSQLDataSourceConfig</param-name> <param-value>zy.pro.wd.xml.MSSQLConfig</param-value> </context-param> <listener> <listener-class>zy.pro.wd.listener.MSSQLDataSourceListener</listener-class> </listener>
(七) 测试配置是否成功,我们在jsp中测试 (1) 测试MS SQL SERVER的JSP页面mssqlDataSourceDemo.jsp,代码如下: <%@ page language="java" import="javax.naming.*" %> <%@ page language="java" import="java.util.*" %> <%@ page language="java" import="java.sql.*" %> <%@ page language="java" import="javax.sql.*" %> <%@ page import ="zy.pro.wd.listener.MSSQLDataSourceListener"%>
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'mssqlDataSourceDemo.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> This is my JSP page. <br> <% Context ctx=new InitialContext(); DataSource ds=(DataSource)ctx.lookup(MSSQLDataSourceListener.JNDI_NAME); Connection con=ds.getConnection(); out.println(con); %> </body> </html>
(2) 测试Oracle数据源的JSP页面为oracleDataSourceDemo.jsp,代码如下: <%@ page language="java" import="javax.naming.*" %> <%@ page language="java" import="java.util.*" %> <%@ page language="java" import="java.sql.*" %> <%@ page language="java" import="javax.sql.*" %> <%@ page language="java" import="zy.pro.wd.listener.OracleDataSourceListener" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'oracleDataSourceDemo.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> This is my JSP page. <br> this is a test of getting the connection from a orace datasource configured using the XML files <br> <% Context ctx=new InitialContext(); DataSource ds=(DataSource)ctx.lookup(OracleDataSourceListener.JNDI_NAME); Connection con=ds.getConnection(); out.println(con); %> </body> </html> (八) 测试结果 (1) MSSQL 的测试结果为: This is my JSP page. this is a test of getting the connection from a orace datasource configured using the XML files oracle.jdbc.driver.OracleConnection@143073a (2) Oracle的测试结果为: This is my JSP page. org.apache.commons.dbcp.PoolableConnection@18facfb
以上程序均调试通过。如果还有问题,和我联系 zhyiwww@163.com. QQ:290390921
总结: (1) 编写数据源配置文件??XML文件 (2) 编写解析类 (3) 编写侦听器类 (4) 在Web.xml中配置数据源 (5) 测试数据源
在本例中,仅仅谈到实现,不涉及到其设计问题。仅供参考。
|
|
|