這是一個Servlet應用。。
該版本用到了Json-lib工具包,關於Json-lib的使用,請參見我的博文
http://blog.csdn.net/jadyer/archive/2011/02/01/6171659.aspx
首先是web.xml檔案
<?xml version="1.0" encoding="UTF-8"?><br /><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"<br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xsi:schemaLocation="http://java.sun.com/xml/ns/javaee<br />http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><br /><servlet><br /><servlet-name>InitProvinceServlet</servlet-name><br /><servlet-class>com.jadyer.servlet.InitProvinceServlet</servlet-class><br /></servlet><br /><servlet><br /><servlet-name>GetCityServlet</servlet-name><br /><servlet-class>com.jadyer.servlet.GetCityServlet</servlet-class><br /></servlet><br /><servlet><br /><servlet-name>GetAreaServlet</servlet-name><br /><servlet-class>com.jadyer.servlet.GetAreaServlet</servlet-class><br /></servlet></p><p><servlet-mapping><br /><servlet-name>InitProvinceServlet</servlet-name><br /><url-pattern>/servlet/InitProvinceServlet</url-pattern><br /></servlet-mapping><br /><servlet-mapping><br /><servlet-name>GetCityServlet</servlet-name><br /><url-pattern>/servlet/GetCityServlet</url-pattern><br /></servlet-mapping><br /><servlet-mapping><br /><servlet-name>GetAreaServlet</servlet-name><br /><url-pattern>/servlet/GetAreaServlet</url-pattern><br /></servlet-mapping></p><p><!-- 在version="2.5"中,可以直接在<welcome-file-list>裡執行Servlet應用 --><br /><welcome-file-list><br /><welcome-file>servlet/InitProvinceServlet</welcome-file><br /></welcome-file-list><br /></web-app>
然後是用來顯示省市三級聯動效果的index.jsp頁面
<%@ page language="java" pageEncoding="UTF-8"%><br /><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><br /><style><br />#area {<br />background-color: #FFFFC0;<br />font-size: 12px;<br />color: green;<br />}<br /></style><br /><script type="text/javascript"><br />var xmlHTTP = new XMLHttpRequest(); //支援Internet Explorer-8.0.6001.18702</p><p>function getCitys(provinceID){<br />//若省份項選中了【==請選擇省份==】則清空城市列表資料,並顯示【==請選擇城市==】<br />if('0' == provinceID){<br />clearCitys();<br />return;<br />}<br />xmlHTTP.open('GET', '${pageContext.request.contextPath}/servlet/GetCityServlet?provinceID='+provinceID, true);<br />xmlHTTP.onreadystatechange = callbackCitys; //設定回呼函數<br />xmlHTTP.setRequestHeader("if-Modified-Since", "0"); //設定不使用瀏覽器緩衝<br />xmlHTTP.send(null); //發送請求<br />}</p><p>function callbackCitys(){<br />if(4==xmlHTTP.readyState && 200==xmlHTTP.status){<br />//此時返回的資料類似於【[{"areas":[],"cityID":4,"cityName":"哈爾濱","description":"著名的冰城","parentID":0},{"areas":[],"cityID":5,"cityName":"佳木斯","description":"傳說的賊城","parentID":0},{"areas":[],"cityID":6,"cityName":"雙鴨山","description":"滿族發源地","parentID":0}]】<br />var citys = eval(xmlHTTP.responseText);<br />clearCitys();<br />var city = document.getElementById("city");<br />for(var i=0; i<citys.length; i++){<br />city.options[i+1] = new Option(citys[i].cityName, citys[i].cityID); //new Option(text,value)<br />}<br />}<br />}</p><p>//清空城市列表資料<br />function clearCitys(){<br />var city = document.getElementById('city');<br />document.getElementById("area").innerHTML = "";<br />city.length = 0;<br />city.options[0] = new Option('==請選擇城市==', '0');<br />}</p><p>function getArea(cityID){<br />if('0' == cityID){<br />document.getElementById("area").innerHTML = "";<br />return;<br />}<br />xmlHTTP.open('GET', '${pageContext.request.contextPath}/servlet/GetAreaServlet?cityID='+cityID, true);<br />xmlHTTP.onreadystatechange = callbackArea;<br />xmlHTTP.setRequestHeader("if-Modified-Since", "0");<br />xmlHTTP.send(null);<br />}</p><p>function callbackArea(){<br />if(4==xmlHTTP.readyState && 200==xmlHTTP.status){<br />//此時返回的資料類似於【{"areas":[{"areas":[],"cityID":13,"cityName":"巴彥縣","description":"我的家鄉","parentID":0},{"areas":[],"cityID":14,"cityName":"延壽縣","description":"延壽山莊","parentID":0},{"areas":[],"cityID":15,"cityName":"木蘭縣","description":"慈航古寺","parentID":0}],"cityID":4,"cityName":"哈爾濱","description":"著名的冰城","parentID":0}】<br />var city = eval('(' + xmlHTTP.responseText + ')');<br />var msg = "<p><b>" + city.cityName +"市為:" + city.description + "</b><br/>";<br />if(0 == city.areas.length){<br />msg += "沒有區縣";<br />}else{<br />msg += "其下有" + city.areas.length + "個區縣,依次為:<br/>";<br />var areas = city.areas;<br />for(var i=0; i<areas.length; i++){<br />msg += ("名稱:" + areas[i].cityName + " 描述:" + areas[i].description + "<br/>");<br />}<br />}<br />msg += "</p>";<br />document.getElementById("area").innerHTML = msg;<br />}<br />}<br /></script></p><p>省份:<br /><select id="province" onchange="getCitys(this.value)"><br /><option value="0">==請選擇省份==</option><br /><c:forEach items="${requestScope.provinces}" var="province"><br /><option value="${province.cityID}">${province.cityName}</option><br /></c:forEach><br /></select><br /> <br />城市:<br /><select id="city" onchange="getArea(this.value)"><br /><option>==請選擇城市==</option><br /></select><br /><div id="area"></div>
然後是用於從資料庫執行查詢操作的CityDao.java
package com.jadyer.dao;</p><p>import java.sql.Connection;<br />import java.sql.PreparedStatement;<br />import java.sql.ResultSet;<br />import java.sql.SQLException;<br />import java.util.ArrayList;<br />import java.util.List;</p><p>import javax.naming.Context;<br />import javax.naming.InitialContext;<br />import javax.naming.NamingException;<br />import javax.sql.DataSource;</p><p>import com.jadyer.model.City;</p><p>/**<br /> * 這裡的代碼,應該重構一下,但為了示範方便,就沒有重構<br /> */<br />public class CityDao {<br />/**<br /> * 根據父ID得到所有一級子類<br /> * @see 如果傳遞為0,則得到所有根節點<br /> */<br />public List<City> findByParentID(int parentID){<br />String sql = "select cityID, cityName, description from city where parentID=?";<br />List<City> citys = new ArrayList<City>();<br />try {<br />Context context = new InitialContext();<br />//有關jdbc/oracleds串連池的配置,參見http://blog.csdn.net/jadyer/archive/2010/11/10/6001023.aspx<br />DataSource ds = (DataSource)context.lookup("java:/comp/env/jdbc/oracleds");<br />Connection conn = ds.getConnection();<br />PreparedStatement pstmt = conn.prepareStatement(sql);<br />pstmt.setInt(1, parentID);<br />ResultSet rs = pstmt.executeQuery();<br />while(rs.next()){<br />citys.add(new City(rs.getInt("cityID"), rs.getString("cityName"), rs.getString("description")));<br />}<br />} catch (NamingException e) {<br />e.printStackTrace();<br />} catch (SQLException e) {<br />e.printStackTrace();<br />}<br />return citys;<br />}</p><p>/**<br /> * 根據ID得到該城市的詳細資料<br /> */<br />public City fingByCityID(int cityID){<br />String sql = "select cityName, description from city where cityID=?";<br />City city = null;<br />try {<br />Context context = new InitialContext();<br />DataSource ds = (DataSource)context.lookup("java:/comp/env/jdbc/oracleds");<br />Connection conn = ds.getConnection();<br />PreparedStatement pstmt = conn.prepareStatement(sql);<br />pstmt.setInt(1, cityID);<br />ResultSet rs = pstmt.executeQuery();<br />while(rs.next()){<br />city = new City(cityID, rs.getString("cityName"), rs.getString("description"));<br />}<br />} catch (NamingException e) {<br />e.printStackTrace();<br />} catch (SQLException e) {<br />e.printStackTrace();<br />}<br />return city;<br />}<br />}
用於儲存City資訊的實體類
package com.jadyer.model;</p><p>import java.util.List;</p><p>public class City {<br />private Integer parentID;<br />private Integer cityID;<br />private String cityName;<br />private String description;<br />private List<City> areas; //新增。。用於儲存該城市下所有區縣的詳細資料</p><p>/* 五個屬性的getter和setter方法略 */</p><p>public City(){}</p><p>public City(Integer cityID, String cityName, String description){<br />this.cityID = cityID;<br />this.cityName = cityName;<br />this.description = description;<br />}<br />}
用於初始化所有省份資訊的InitProvinceServlet.java
package com.jadyer.servlet;</p><p>import java.io.IOException;</p><p>import javax.servlet.ServletException;<br />import javax.servlet.http.HttpServlet;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;</p><p>import com.jadyer.dao.CityDao;</p><p>@SuppressWarnings("serial")<br />public class InitProvinceServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {<br />CityDao cityDao = new CityDao();<br />//擷取所有省份的資訊<br />request.setAttribute("provinces", cityDao.findByParentID(0));<br />request.getRequestDispatcher("/index.jsp").forward(request, response);<br />}<br />}
用於擷取指定省份下的所有城市資訊的GetCityServlet.java
package com.jadyer.servlet;</p><p>import java.io.IOException;<br />import java.util.List;</p><p>import javax.servlet.ServletException;<br />import javax.servlet.http.HttpServlet;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;</p><p>import net.sf.json.JSONArray;</p><p>import com.jadyer.dao.CityDao;<br />import com.jadyer.model.City;</p><p>@SuppressWarnings("serial")<br />public class GetCityServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {<br />response.setContentType("text/html; charset=UTF-8");<br />int provinceID = Integer.parseInt(request.getParameter("provinceID"));<br />CityDao cityDao = new CityDao();<br />//返回該省份下的所有城市的資訊<br />List<City> citys = cityDao.findByParentID(provinceID);<br />JSONArray jsonObject = JSONArray.fromObject(citys);<br />response.getWriter().println(jsonObject.toString());<br />}<br />}
用於擷取指定城市下的所有區縣資訊的GetAreaServlet.java
package com.jadyer.servlet;</p><p>import java.io.IOException;<br />import java.util.List;</p><p>import javax.servlet.ServletException;<br />import javax.servlet.http.HttpServlet;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;</p><p>import net.sf.json.JSONObject;</p><p>import com.jadyer.dao.CityDao;<br />import com.jadyer.model.City;</p><p>@SuppressWarnings("serial")<br />public class GetAreaServlet extends HttpServlet {<br />public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {<br />response.setContentType("text/html; charset=UTF-8");<br />int cityID = Integer.parseInt(request.getParameter("cityID"));<br />CityDao cityDao = new CityDao();<br />//得到該城市下所有區縣的詳細資料的集合<br />List<City> areas = cityDao.findByParentID(cityID);<br />//得到當前城市的詳細資料<br />City city22 = cityDao.fingByCityID(cityID);<br />city22.setAreas(areas);<br />JSONObject jsonObject = JSONObject.fromObject(city22);<br />response.getWriter().println(jsonObject.toString());<br />}<br />}
最後是資料庫指令碼檔案
--Oracle 11g<br />--建立表格<br />create table city(<br />id number(3) primary key,<br />parentID number(3), --0表示根節點<br />cityID number(3),<br />cityName varchar(20),<br />description varchar(20)<br />)</p><p>--建立序列<br />create sequence city_sequence increment by 1 start with 1 nomaxvalue nocycle;</p><p>--添加一級菜單<br />insert into city values(city_sequence.nextval, 0, 1, '黑龍江', '東北三省的黑龍江省');<br />insert into city values(city_sequence.nextval, 0, 2, '吉林省', '東北三省的吉林省');<br />insert into city values(city_sequence.nextval, 0, 3, '遼寧省', '東北三省的遼寧省');<br />--添加二級菜單<br />insert into city values(city_sequence.nextval, 1, 4, '哈爾濱', '著名的冰城');<br />insert into city values(city_sequence.nextval, 1, 5, '佳木斯', '傳說的賊城');<br />insert into city values(city_sequence.nextval, 1, 6, '雙鴨山', '滿族發源地');<br />insert into city values(city_sequence.nextval, 2, 7, '長春', '中國汽車之都');<br />insert into city values(city_sequence.nextval, 2, 8, '遼源', '中國琵琶之鄉');<br />insert into city values(city_sequence.nextval, 2, 9, '通化', '中國醫藥之城');<br />insert into city values(city_sequence.nextval, 3, 10, '瀋陽', '中國優秀旅遊城市');<br />insert into city values(city_sequence.nextval, 3, 11, '大連', '中國第一海軍廣場');<br />insert into city values(city_sequence.nextval, 3, 12, '鐵嶺', '中國小品王的家鄉');<br />--添加三級菜單<br />--這裡只提供了黑龍江省的三級聯動資料,關於其它省份的資料,請自行添加<br />insert into city values(city_sequence.nextval, 4, 13, '巴彥縣', '我的家鄉');<br />insert into city values(city_sequence.nextval, 4, 14, '延壽縣', '延壽山莊');<br />insert into city values(city_sequence.nextval, 4, 15, '木蘭縣', '慈航古寺');<br />insert into city values(city_sequence.nextval, 5, 16, '撫遠縣', '白四爺廟');<br />insert into city values(city_sequence.nextval, 5, 17, '湯原縣', '西郎君城');<br />insert into city values(city_sequence.nextval, 5, 18, '樺川縣', '魚米之鄉');<br />insert into city values(city_sequence.nextval, 6, 19, '集賢縣', '大菩提寺');<br />insert into city values(city_sequence.nextval, 6, 20, '寶清縣', '雁窩之島');<br />insert into city values(city_sequence.nextval, 6, 21, '友誼縣', '中蘇友誼');