原生AJAX或jQuery实现二级联动选择以及解析XML和JSON数据格式
本文以省和城市为例来实现二级联动选择框,包含了DOM4J生成XML数据的方式和使用JSONArray类生成JSON数据格式的方式。以及服务器返回的数据类型XML和JSON格式在JavaScript和jQuery中的解析方法。
项目包结构图:
ProName
|--src
| |-- com
| |--ajax
| |--bean
| | |--City.java
| | |--CreateJSONObject.java
| |--servlet
| |--SelectCityServlet.java
|--WebRoot
|--js
| |--jquery.js
| |--selectCity.js
| |--selectCityjQuery.js
|--WEB-INF
| |--c.tld
| |--web.xml
|--selectCity.jsp
1. 页面代码(selectCity.jsp)
<%@ page language="java" import="java.util.*,com.ajax.bean.City" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <% String path = request.getContextPath(); //初始化省份选择框数据 List<City> provinceList = City.getProvinceList(); request.setAttribute("provinceList", provinceList); %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>省和城市的级联选择实例</title> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/selectCity.js"></script> <script type="text/javascript" src="js/selectCityjQuery.js"></script> </head> <body> <p /> 一、AJAX原生方式实现省和城市的级联选择: <p /> <table cellspacing="0" cellpadding="2" align="left" border="0"> <tr> <td style="width: 20px"> </td> <td> 省份: </td> <td style="width: 100px"> <select id="provinceIdSelect" style="width: 80px" onchange="selectProvince()"> <option value="" selected> 全部 </option> <c:if test="${!empty provinceList }"> <c:forEach var="province" items="${provinceList}"> <option value="${province.id }" ${province.id==provinceId?'selected':''}> ${province.name} </option> </c:forEach> </c:if> </select> </td> <td style="width: 20px"> </td> <td> 城市: </td> <td style="width: 100px"> <select id="cityIdSelect" style="width: 80px"> <option value="0"> 全部 </option> </select> </td> </tr> </table> <br /> <br /> 二、jQuery方式实现省和城市的级联选择: <p /> <table cellspacing="0" cellpadding="2" align="left" border="0"> <tr> <td style="width: 20px"> </td> <td> 省份: </td> <td style="width: 100px"> <select id="provinceIdSelectJ" style="width: 80px" onchange="selectProvinceJ()"> <option value="" selected> 全部 </option> <c:if test="${!empty provinceList }"> <c:forEach var="province" items="${provinceList}"> <option value="${province.id }" ${province.id==provinceId?'selected':''}> ${province.name} </option> </c:forEach> </c:if> </select> </td> <td style="width: 20px"> </td> <td> 城市: </td> <td style="width: 100px"> <select id="cityIdSelectJ" style="width: 80px"> <option value="0"> 全部 </option> </select> </td> </tr> </table> </body> </html>
2. JS代码
selectCity.js
//创建AJAX引擎 function createXmlhttp () { var xhr; if (window.XMLHttpRequest) { //针对FireFox,Mozillar,Opera,Safari,IE7,IE8 xhr = new XMLHttpRequest(); //针对某些特定版本的mozillar浏览器的BUG进行修正 if (xhr.overrideMimeType) { xhr.overrideMimeType("text/xml"); } } else if (window.ActiveXObject) { //针对IE6,IE5.5,IE5 //两个可以用于创建XMLHTTPRequest对象的控件名称,保存在一个js的数组中 //排在前面的版本较新 var activexName = ["MSXML2.XMLHTTP","Microsoft.XMLHTTP"]; for (var i = 0; i < activexName.length; i++) { try{ //取出一个控件名进行创建,如果创建成功就终止循环 //如果创建失败,回抛出异常,然后可以继续循环,继续尝试创建 xhr = new ActiveXObject(activexName[i]); break; } catch(e){ } } } return xhr; } var xmlhttp; //发送请求 function sendRequest(url ,content){ xmlhttp = createXmlhttp (); xmlhttp.onreadystatechange = processResponse; xmlhttp.open("post",url); xmlhttp.setRequestHeader("content-type","application/x-www-form-urlencoded"); xmlhttp.send(content); } //回调方法 function processResponse(){ if (xmlhttp.readyState == 4 ) { if (xmlhttp.status == 200 ){ //设置城市选择框为默认值 setCityDefault(); //获得服务器返回的XML,并转为DOC对象 var xmldoc = xmlhttp.responseXML; //DOM解析XML domParseXml(xmldoc); //JSON格式解析 // parseJson(xmlhttp.responseText); } } } //DOM解析XML function domParseXml(xmldoc){ //遍历服务器响应的XML,并创建对应option标签 //获取显示城市的选择框 var cityId_obj = document.getElementById("cityIdSelect"); //获取具有指定标记名的所有元素节点 // var city = xmldoc.getElementsByTagName("city"); var city = xmldoc.selectNodes("/cities/city"); for (var i=0; i<city.length; i++ ) { //获取节点文本 var id_txt = city[i].childNodes[0].childNodes[0].data; //data和nodeValue都可以 var name_txt = city[i].childNodes[1].childNodes[0].nodeValue; //创建节点对象 var id_obj = document.createTextNode(id_txt); var name_obj = document.createTextNode(name_txt); //创建城市<option> var cityOption = document.createElement("option"); //设置value属性 cityOption.setAttribute("value",id_obj); //设置name属性 cityOption.appendChild(name_obj); cityId_obj.appendChild(cityOption); } } //解析JSON数据 function parseJson(obj){ //通过eval() 函数可以将JSON字符串转化为对象 var json = eval(obj) //获取显示城市的选择框 var cityId_obj = document.getElementById("cityIdSelect"); //遍历JSON数组 for (var ind in json) { //创建城市<option> var cityOption = document.createElement("option"); //创建节点对象,将文本转为dom对象 var id_obj = document.createTextNode(json[ind].id); var name_obj = document.createTextNode(json[ind].name); //设置value属性 cityOption.setAttribute("value",id_obj); //设置name属性 cityOption.appendChild(name_obj); cityId_obj.appendChild(cityOption); } } //改变省选择框触发事件,ajax异步请求 function selectProvince(){ var provinceId_obj = document.getElementById("provinceIdSelect"); if ( provinceId_obj.value != "" ) { var url = "selectCity"; var content = "provinceId=" + provinceId_obj.value ; //发送AJAX请求 sendRequest(url, content); } else { //设置城市选择框为默认值 setCityDefault(); } } //设置城市选择框为默认值 function setCityDefault(){ //获取显示城市的选择框 var cityId_obj = document.getElementById("cityIdSelect"); //清除原来的select值 cityId_obj.options.length=0; //添加默认的option标签 //创建option标签 var defOption_obj = document.createElement("option"); defOption_obj.setAttribute("value","0"); //设置默认选择 var defName_obj = document.createTextNode("全部") defOption_obj.appendChild(defName_obj); cityId_obj.appendChild(defOption_obj); }
selectCityjQuery.js,jquery版本为1.2.6
//创建异步请求 function selectProvinceJ(){ var pidNode = $("#provinceIdSelectJ"); if ( pidNode.val() != "" ) { //第一种:服务器以JSON响应 // jsonResponseProcess(pidNode); //第二种:服务器以XML响应 xmlResponseProcess(pidNode); } else { //设置城市选择框为默认值 setCityDefaultJ(); } } //请求后,返回JSON数据类型 function jsonResponseProcess(pidNode){ var pid = pidNode.val(); $.post("selectCity", {provinceId : pid}, function(json){ //获取显示城市的选择框 var cidNode = $("#cityIdSelectJ"); //清空之前内容 cidNode.empty(); $(json).each(function(i){ cidNode.append("<option value='" + json[i].id + "'>" + json[i].name + "</option>" ); }); }, "json" //xml, html, script, json, text, _default ); } //请求后,返回XML数据类型 function xmlResponseProcess(pidNode){ var pid = pidNode.val(); $.post("selectCity", {provinceId : pid}, function(xml){ //获取显示城市的选择框 var cidNode = $("#cityIdSelectJ"); //清空之前内容 cidNode.empty(); var id_txt; var name_txt; $(xml).find("city").each(function(i){ //children()先取得ID对象,text()再取值 id_txt = $(this).children("id").text(); //另一种取对象方法 name_txt = $("name",this).text(); cidNode.append("<option value='" + id_txt + "'>" + name_txt + "</option>" ); }); }, "xml" //xml, html, script, json, text, _default ); } //设置城市选择框为默认值 function setCityDefaultJ(){ var cidNode = $("#cityIdSelectJ"); //删除匹配的元素集合中所有的子节点。 cidNode.empty(); cidNode.append("<option>全部</option>"); }
3. Servlet/javaBean代码
SelectCityServlet.java
package com.ajax.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ajax.bean.City; import com.ajax.bean.CreateJSONObject; import com.ajax.bean.CreateXMLText; /** * @author [email protected] */ public class SelectCityServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 生成XML和文本文件返回 response.setContentType("text/xml"); response.setCharacterEncoding("UTF-8"); String provinceId = request.getParameter("provinceId"); String provinceXml = null; List<City> cityList = null; try { if (null != provinceId && !"".equals(provinceId)) { // 根据id获取该省的城市列表 cityList = City.getCityList(Long.valueOf(provinceId)); //DOM4J方式生成XML provinceXml = dom4jToXml(cityList); //JSON数据格式返回 // CreateJSONObject json = new CreateJSONObject(); // provinceXml = json.nativeToJson(cityList); // provinceXml = json.jsonArrayToJson(cityList); } response.getWriter().print(provinceXml); } catch (Exception e) { e.printStackTrace(); } } /** * DOM4J生成XML * * @param list * @return */ public String dom4jToXml(List<City> list) { String strXml = null; try { if (null != list && !list.isEmpty()) { DocumentFactory df = DocumentFactory.getInstance(); // org.dom4j.Document doc = DocumentHelper.createDocument(); org.dom4j.Document doc = df.createDocument("UTF-8"); // 创建根节点 org.dom4j.Element citiesElt = doc.addElement("cities"); for (City po : list) { // 在节点<cities>下增加子节点<city> org.dom4j.Element cityElt = citiesElt.addElement("city"); // 在节点<city>下增加子节点<id> org.dom4j.Element idElt = cityElt.addElement("id"); idElt.addText(String.valueOf(po.getId())); // 在节点<city>下增加子节点<name> org.dom4j.Element nameElt = cityElt.addElement("name"); nameElt.addText(po.getName()); } // 无样式的 strXml = doc.asXML(); } } catch (IOException e) { e.printStackTrace(); } System.out.println("DOM4J:" + strXml); return strXml; } }
City.java
package com.ajax.bean; import java.util.ArrayList; import java.util.List; public class City { // 主键 private Long id; // parentId为0代表是省份,否则为城市 private Long parentId; // 名字 private String name; /** * 默认构造器 */ public City() { } /** * @param id * @param parentId * @param name */ public City(Long id, Long parentId, String name) { super(); this.id = id; this.parentId = parentId; this.name = name; } /** * @return the id */ public Long getId() { return id; } /** * @param id * the id to set */ public void setId(Long id) { this.id = id; } /** * @return the parentId */ public Long getParentId() { return parentId; } /** * @param parentId * the parentId to set */ public void setParentId(Long parentId) { this.parentId = parentId; } /** * @return the name */ public String getName() { return name; } /** * @param name * the name to set */ public void setName(String name) { this.name = name; } @Override public String toString() { return "id=" + this.id + ",parentId=" + this.parentId + ",name=" + this.name; } /** * 测试用 获取省份 * * @return */ public static List<City> getProvinceList() { List<City> provinceList = new ArrayList<City>(); City city = new City(101L, 0L, "湖南省"); provinceList.add(city); city = new City(102L, 0L, "广东省"); provinceList.add(city); city = new City(103L, 0L, "浙江省"); provinceList.add(city); return provinceList; } /** * 测试用 获取城市 * * @return */ public static List<City> getCityList(Long provinceId) { List<City> cityList = new ArrayList<City>(); City city = null; // 编写湖南的城市 if (provinceId.equals(101L)) { city = new City(151L, 101L, "长沙市"); cityList.add(city); city = new City(152L, 101L, "永州市"); cityList.add(city); city = new City(153L, 101L, "衡阳市"); cityList.add(city); city = new City(154L, 101L, "郴州市"); cityList.add(city); city = new City(155L, 101L, "常德市"); cityList.add(city); } else if (provinceId.equals(102L)) { // 编写广东的城市 city = new City(171L, 102L, "广州市"); cityList.add(city); city = new City(172L, 102L, "深圳市"); cityList.add(city); city = new City(173L, 102L, "东莞市"); cityList.add(city); city = new City(174L, 102L, "中山市"); cityList.add(city); city = new City(175L, 102L, "佛山市"); cityList.add(city); city = new City(176L, 102L, "江门市"); cityList.add(city); } else if (provinceId.equals(103L)) { // 编写浙江的城市 city = new City(191L, 103L, "杭州市"); cityList.add(city); city = new City(192L, 103L, "宁波市"); cityList.add(city); } return cityList; } public static void main(String[] args) { List<City> province = City.getProvinceList(); for (City p : province) { System.out.println(p); } List<City> city = City.getCityList(101L); for (City c : city) { System.out.println(c); } } }
CreateJSONObject.java
package com.ajax.bean; import java.util.List; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /** * 生成json的数据格式 * * @author [email protected] */ public class CreateJSONObject { // 采用json的数据格式返回对象信息 // 冒号后可以为[{pid1:{id:"",name:""}, pid2:{id:"",name:""}}] // json格式: // [{ // id: "city.getId()", // name: "city.getName()", // }, // { // id: "city.getId()", // name: "city.getName()", // }] /** * 字符串拼接的方式 * @param list * @return 如:[{id:151,name:'长沙市'},{id:152,name:'永州市'}] */ public String nativeToJson(List<City> list) { StringBuilder jsonStr = new StringBuilder(list.size()); if (null != list && !list.isEmpty()) { int i=0; jsonStr.append("["); for (City po : list) { jsonStr.append("{id:") .append(po.getId()) .append(",name:'") .append(po.getName()) .append("'}"); //最后不用加逗号 if ( (++i) != list.size() ){ jsonStr.append(","); } } jsonStr.append("]"); } System.out.println("Native:" + jsonStr.toString()); return jsonStr.toString(); } /** * json-lib.jar * 依赖包:commons-logging.jar * common.lang.jar * commons-beanutils.jar * commons-collections.jar * ezmorph.jar * @param list * @return */ public String jsonArrayToJson(List<City> list ) { //第一种方式,返回[{"parentId":101,"citys":[],"name":"长沙市","id":151},{"parentId":101,"citys":[],"name":"永州市","id":152}] // JSONArray js = JSONArray.fromObject(list); //第二种方式,返回[{"name":"长沙市","id":151},{"name":"永州市","id":152}] JSONArray js = new JSONArray(); if (null != list && !list.isEmpty()) { JSONObject obj = null; for ( City po: list ){ obj = new JSONObject(); obj.put("id", po.getId()); obj.put("name", po.getName()); js.add(obj); obj = null; } } System.out.println("JSONArray:" + js.toString()); return js.toString(); } public static void main(String[] args) { List<City> list = City.getCityList(101L); CreateJSONObject json = new CreateJSONObject(); json.nativeToJson(list); json.jsonArrayToJson(list); } }
4. web.xml
<servlet> <servlet-name>SelectCity</servlet-name> <servlet-class>com.ajax.SelectCityServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SelectCity</servlet-name> <url-pattern>/selectCity</url-pattern> </servlet-mapping>