在Web应用中使用XML文件配置数据源
作者: 文章来源:
发布日期:2007年04月22日 浏览次数:656次
在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) 测试数据源
在本例中,仅仅谈到实现,不涉及到其设计问题。仅供参考。