不少朋友说ajax in action 第9章的程序跑不起来,本人比较熟悉j2ee,就将其改造成j2ee版演示给大家。使用Tomcat5.5,第9章后面的重构后的也差不多
源码下载重构源码下载
运行:

1.数据库表就一个:

2.DoubleComboXML.java
package mypack;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class DoubleComboXML extends HttpServlet
{


public DoubleComboXML()
{
super();
System.out.println("servlet:DoubleComboXML");
}


public void destroy()
{
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}

private void process(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException
{

response.setContentType("text/xml");
PrintWriter out = response.getWriter();

String strQuery = request.getParameter("q");
String strForm = request.getParameter("f");
String strElem = request.getParameter("e");

String strSql = "select * from Territories where regionid=" + strQuery;
Connection connection = null;
PreparedStatement pstm = null;
ResultSet rs = null;

try
{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
connection = DriverManager
.getConnection(
"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=ajax",
"sa", "sa");
pstm = connection
.prepareStatement("select * from Territories where regionid=" + strQuery);
rs = pstm.executeQuery();

} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();

} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}

StringBuffer strXML = new StringBuffer();
strXML.append("<?xml version=\"1.0\" ?>");
strXML.append("<selectChoice>");
strXML.append("<selectElement>");
strXML.append("<formName>" + strForm + "</formName>");
strXML.append("<formElem>" + strElem + "</formElem>");
strXML.append("</selectElement>");


try
{

if (!rs.wasNull())
{

strXML.append("<entry>");
strXML.append("<optionText>Select A Territory</optionText>");
strXML.append("<optionValue>-1</optionValue>");
strXML.append("</entry>");


while (rs.next())
{
strXML.append("<entry>");
strXML.append("<optionText>" + rs.getString("TerritoryDc") + "</optionText>");
strXML.append("<optionValue>" + rs.getInt("TerritoryID") + "</optionValue>");
strXML.append("</entry>");
}
}

} catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}

strXML.append("</selectChoice>");
out.write(strXML.toString());
out.close();
}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException
{

process(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException
{

process(request, response);
}


public void init() throws ServletException
{
// Put your code here
}

}

3.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>DoubleComboXML</servlet-name>
<servlet-class>mypack.DoubleComboXML</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>DoubleComboXML</servlet-name>
<url-pattern>/DoubleComboXML</url-pattern>
</servlet-mapping>

</web-app>

4.MyJsp.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Double Combo - Ajax In Action</title>
<script type="text/javascript" src="js/net.js"></script>

<script type="text/javascript">

function FillTerritory(oElem,oTarget)
{
var strValue = oElem.options[
oElem.selectedIndex].value;
var url = 'DoubleComboXML';
var strParams = 'q=' + strValue +
"&f=" + oTarget.form.name +
"&e=" + oTarget.name;
var loader1 = new
net.ContentLoader(url,FillDropDown,null,
"POST",strParams);
}

function FillDropDown()
{
var xmlDoc = this.req.responseXML.documentElement;

var xSel = xmlDoc.
getElementsByTagName('selectElement')[0];
var strFName = xSel.
childNodes[0].firstChild.nodeValue;
var strEName = xSel.
childNodes[1].firstChild.nodeValue;
var objDDL = document.forms[strFName].
elements[strEName];
objDDL.options.length = 0;
var xRows = xmlDoc.
getElementsByTagName('entry');

for(i=0;i<xRows.length;i++)
{
var theText = xRows[i].
childNodes[0].firstChild.nodeValue;
var theValue = xRows[i].
childNodes[1].firstChild.nodeValue;
var option = new Option(theText,
theValue);
objDDL.options.add(option,
objDDL.options.length);
}
}
</script>
</head>
<body>
<form name="Form1" ID="Form1">
<select name="ddlRegion" onchange="FillTerritory(this,document.Form1.ddlTerritory)" ID="Select1">
<option value="-1">Pick A Region</option>
<option value="1">Eastern</option>
<option value="2">Western</option>
<option value="3">Northern</option>
<option value="4">Southern</option>
</select>
<select name="ddlTerritory" ID="Select2"></select>
</form>
</body>
</html>

5.net.js

/**//*
url-loading object and a request queue built on top of it
*/


/**//* namespacing object */
var net=new Object();

net.READY_STATE_UNINITIALIZED=0;
net.READY_STATE_LOADING=1;
net.READY_STATE_LOADED=2;
net.READY_STATE_INTERACTIVE=3;
net.READY_STATE_COMPLETE=4;



/**//*--- content loader object for cross-browser requests ---*/

net.ContentLoader=function(url,onload,onerror,method,params,contentType)
{
this.req=null;
this.onload=onload;
this.onerror=(onerror) ? onerror : this.defaultError;
this.loadXMLDoc(url,method,params,contentType);
}


net.ContentLoader.prototype.loadXMLDoc=function(url,method,params,contentType)
{

if (!method)
{
method="GET";
}

if (!contentType && method=="POST")
{
contentType='application/x-www-form-urlencoded';
}

if (window.XMLHttpRequest)
{
this.req=new XMLHttpRequest();

} else if (window.ActiveXObject)
{
this.req=new ActiveXObject("Microsoft.XMLHTTP");
}

if (this.req)
{

try
{
var loader=this;

this.req.onreadystatechange=function()
{
net.ContentLoader.onReadyState.call(loader);
}
this.req.open(method,url,true);

if (contentType)
{
this.req.setRequestHeader('Content-Type', contentType);
}
this.req.send(params);

}catch (err)
{
this.onerror.call(this);
}
}
}



net.ContentLoader.onReadyState=function()
{
var req=this.req;
var ready=req.readyState;

if (ready==net.READY_STATE_COMPLETE)
{
var httpStatus=req.status;

if (httpStatus==200 || httpStatus==0)
{
this.onload.call(this);

}else
{
this.onerror.call(this);
}
}
}


net.ContentLoader.prototype.defaultError=function()
{
alert("error fetching data!"
+"\n\nreadyState:"+this.req.readyState
+"\nstatus: "+this.req.status
+"\nheaders: "+this.req.getAllResponseHeaders());
}



