最近做的项目中涉及到5,6级的级联菜单,用以前那种纯JavaScript做起来实在是太低效了,页面响应慢得跟286一样。。。于是上网找AJAX实现的级联菜单,找来找去找不到用DB+JSP+AJAX实现的。索性把人家的代码拿来改了改,自己做了一个。
我之所以采用这个代码作为修改的蓝本,是因为这个代码的服务端处理程序返回的是标准的XML序列,客户端的JavaScript通过
var res = XMLHttpReq.responseXML.getElementsByTagName(String)
的方式来解析这个XML序列,再通过类似于
res[i].firstChild.data
的方式遍历这个XML序列,从而找到所要的数据。这样可以实现比较大的数据的AJAX操作,比那些只返回简单String的例子要好得多了!反正我最讨厌手动解析字符串了!
menu.jsp(文件的编码也是UTF-8,我用EmEditor写的,右下角那里可以更改文档的编码格式)
<%
@ page language
=
"
java
"
import
=
"
java.util.*,java.sql.*
"
pageEncoding
=
"
UTF-8
"
%>
<%
request.setCharacterEncoding( " UTF-8 " );
response.setContentType( " text/html;charset=UTF-8 " );
%>
< html >
< head >
< META http-equiv =Content-Type content ="text/html; charset=UTF-8" >
<!-- LINK href="images/css.css" type=text/css rel=stylesheet -->
</ head >
<%
String driver = " org.apache.derby.jdbc.EmbeddedDriver " ;
String dbName = " /derby/demo/databases/toursdb " ;
String connectionURL = " jdbc:derby: " + dbName;
Connection conn = null ;
Statement st = null ;
ResultSet rs = null ;
List cities = new ArrayList();
try{
Class.forName(driver);
} catch(java.lang.ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(connectionURL);
st = conn.createStatement();
rs = st.executeQuery( " SELECT distinct COUNTRY FROM cities order by COUNTRY " );
while (rs.next())
{
cities.add(rs.getString( 1 ));
}
rs.close();
st.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
%>
< body >
< script language ="javascript" >
var XMLHttpReq;
var currentSort;
// 创建XMLHttpRequest对象
function createXMLHttpRequest() {
if (window.XMLHttpRequest) { // Mozilla 浏览器
XMLHttpReq = new XMLHttpRequest();
}
else if (window.ActiveXObject) { // IE浏览器
try {
XMLHttpReq = new ActiveXObject( " Msxml2.XMLHTTP " );
} catch (e) {
try {
XMLHttpReq = new ActiveXObject( " Microsoft.XMLHTTP " );
} catch (e) {}
}
}
}
// 发送请求函数
function sendRequest(url) {
createXMLHttpRequest();
XMLHttpReq.open( " GET " , url, true );
XMLHttpReq.onreadystatechange = processResponse; // 指定响应函数
XMLHttpReq.send( null ); // 发送请求
}
// 处理返回信息函数
function processResponse() {
if (XMLHttpReq.readyState == 4 ) { // 判断对象状态
if (XMLHttpReq.status == 200 ) { // 信息已经成功返回,开始处理信息
updateMenu();
} else { // 页面不正常
alert( " 您所请求的页面有异常。 " );
}
}
}
// 更新菜单函数
function updateMenu() {
var res = XMLHttpReq.responseXML.getElementsByTagName( " res " )
/* *下面是用innerHTML输出控件内容的一般用法* */
// var subMenu = "";
// for(var i = 0; i < res.length; i++) {
// subMenu = subMenu + " " + res[i].firstChild.data + "";
// }
// currentSort.innerHTML = subMenu;
var list = document.all.list;
list.options.length = 0 ;
list.add( new Option( " ---请选择--- " , "" ));
for ( var i = 0 ;i < res.length;i ++ ){
list.add( new Option(res[i].firstChild.data,res[i].firstChild.data));
}
}
// 创建级联菜单函数
function showSubMenu(obj) {
// currentSort =document.getElementById(obj);
// currentSort.parentNode.style.display = "";
sendRequest( " menujsp.jsp?sort= " + obj);
/* *下面这一句的作用是:每次选择后回到第一个选项* */
// document.all.mli.options[0].selected=true;
}
</ script >
< select onchange ="showSubMenu(this.options[this.options.selectedIndex].value)" name ="mli" style ="width:150px" >
< option value ='' > ---请选择--- </ option >
<%
for ( int i = 0 ;i < cities.size();i ++ )
{
out.println( " <option value=' " + cities.get(i) + " '> " + cities.get(i) + " </option> " );
}
%>
</ select >
< select name ="list" onchange ="if(this.selectedIndex)alert(this.options[this.options.selectedIndex].value)" style ="width:100px" >
< option name ="" > ---请选择--- </ option >
</ select >
</ body >
</ html >
menujsp.jsp(文档编码格式也是UTF-8)
<%
request.setCharacterEncoding( " UTF-8 " );
response.setContentType( " text/html;charset=UTF-8 " );
%>
< html >
< head >
< META http-equiv =Content-Type content ="text/html; charset=UTF-8" >
<!-- LINK href="images/css.css" type=text/css rel=stylesheet -->
</ head >
<%
String driver = " org.apache.derby.jdbc.EmbeddedDriver " ;
String dbName = " /derby/demo/databases/toursdb " ;
String connectionURL = " jdbc:derby: " + dbName;
Connection conn = null ;
Statement st = null ;
ResultSet rs = null ;
List cities = new ArrayList();
try{
Class.forName(driver);
} catch(java.lang.ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(connectionURL);
st = conn.createStatement();
rs = st.executeQuery( " SELECT distinct COUNTRY FROM cities order by COUNTRY " );
while (rs.next())
{
cities.add(rs.getString( 1 ));
}
rs.close();
st.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
%>
< body >
< script language ="javascript" >
var XMLHttpReq;
var currentSort;
// 创建XMLHttpRequest对象
function createXMLHttpRequest() {
if (window.XMLHttpRequest) { // Mozilla 浏览器
XMLHttpReq = new XMLHttpRequest();
}
else if (window.ActiveXObject) { // IE浏览器
try {
XMLHttpReq = new ActiveXObject( " Msxml2.XMLHTTP " );
} catch (e) {
try {
XMLHttpReq = new ActiveXObject( " Microsoft.XMLHTTP " );
} catch (e) {}
}
}
}
// 发送请求函数
function sendRequest(url) {
createXMLHttpRequest();
XMLHttpReq.open( " GET " , url, true );
XMLHttpReq.onreadystatechange = processResponse; // 指定响应函数
XMLHttpReq.send( null ); // 发送请求
}
// 处理返回信息函数
function processResponse() {
if (XMLHttpReq.readyState == 4 ) { // 判断对象状态
if (XMLHttpReq.status == 200 ) { // 信息已经成功返回,开始处理信息
updateMenu();
} else { // 页面不正常
alert( " 您所请求的页面有异常。 " );
}
}
}
// 更新菜单函数
function updateMenu() {
var res = XMLHttpReq.responseXML.getElementsByTagName( " res " )
/* *下面是用innerHTML输出控件内容的一般用法* */
// var subMenu = "";
// for(var i = 0; i < res.length; i++) {
// subMenu = subMenu + " " + res[i].firstChild.data + "";
// }
// currentSort.innerHTML = subMenu;
var list = document.all.list;
list.options.length = 0 ;
list.add( new Option( " ---请选择--- " , "" ));
for ( var i = 0 ;i < res.length;i ++ ){
list.add( new Option(res[i].firstChild.data,res[i].firstChild.data));
}
}
// 创建级联菜单函数
function showSubMenu(obj) {
// currentSort =document.getElementById(obj);
// currentSort.parentNode.style.display = "";
sendRequest( " menujsp.jsp?sort= " + obj);
/* *下面这一句的作用是:每次选择后回到第一个选项* */
// document.all.mli.options[0].selected=true;
}
</ script >
< select onchange ="showSubMenu(this.options[this.options.selectedIndex].value)" name ="mli" style ="width:150px" >
< option value ='' > ---请选择--- </ option >
<%
for ( int i = 0 ;i < cities.size();i ++ )
{
out.println( " <option value=' " + cities.get(i) + " '> " + cities.get(i) + " </option> " );
}
%>
</ select >
< select name ="list" onchange ="if(this.selectedIndex)alert(this.options[this.options.selectedIndex].value)" style ="width:100px" >
< option name ="" > ---请选择--- </ option >
</ select >
</ body >
</ html >
<
%@ page contentType
=
"
text/html; charset=UTF-8
"
import
=
"
java.util.*,java.sql.*
"
%
>
< %
String sort = request.getParameter( " sort " );
String driver = " org.apache.derby.jdbc.EmbeddedDriver " ;
String dbName = " /derby/demo/databases/toursdb " ;
String connectionURL = " jdbc:derby: " + dbName;
Connection conn = null;
Statement st = null;
ResultSet rs = null;
List cities = new ArrayList();
try {
Class .forName(driver);
} catch (java.lang.ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(connectionURL);
st = conn.createStatement();
rs = st.executeQuery( " SELECT CITY_NAME FROM cities where COUNTRY=' " + sort + " ' " );
while (rs.next())
{
cities.add(rs.getString( 1 ));
}
rs.close();
st.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
response.setContentType( " text/xml; charset=UTF-8 " );
response.setHeader( " Cache-Control " , " no-cache " );
out.println( " <response> " );
for ( int i = 0 ;i < cities.size();i ++ )
{
out.println( " <res> " + cities.get(i).toString() + " </res> " );
}
out.println( " </response> " );
out.close();
% >
< %
String sort = request.getParameter( " sort " );
String driver = " org.apache.derby.jdbc.EmbeddedDriver " ;
String dbName = " /derby/demo/databases/toursdb " ;
String connectionURL = " jdbc:derby: " + dbName;
Connection conn = null;
Statement st = null;
ResultSet rs = null;
List cities = new ArrayList();
try {
Class .forName(driver);
} catch (java.lang.ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection(connectionURL);
st = conn.createStatement();
rs = st.executeQuery( " SELECT CITY_NAME FROM cities where COUNTRY=' " + sort + " ' " );
while (rs.next())
{
cities.add(rs.getString( 1 ));
}
rs.close();
st.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
response.setContentType( " text/xml; charset=UTF-8 " );
response.setHeader( " Cache-Control " , " no-cache " );
out.println( " <response> " );
for ( int i = 0 ;i < cities.size();i ++ )
{
out.println( " <res> " + cities.get(i).toString() + " </res> " );
}
out.println( " </response> " );
out.close();
% >
数据库版本是:db-derby-10.3.1.4,可以去 www.apache.org下载。
把db-derby-10.3.1.4-bin.zip解压到c:\derby下,用的示例数据库是c: /derby/demo/databases/toursdb,注意路径。
然后把derby下的derby.jar解压到用于启动Tomcat的那个JRE的ext目录下,重启TOMCAT,打开浏览器,访问menu.jsp即可看到效果。
三级联动的效果:
下载本例的JSP代码: ajax_db_jsp_demo.rar
三级联动下拉菜单:three_ajax_select_with_db.zip
http://www.blogjava.net/ducktsmt/articles/138469.html