fzb215 发表于 2013-1-29 12:18:16

原生AJAX或jQuery实现二级联动选择以及解析XML和JSON数据格式

原生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);                   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解析XMLdomParseXml(xmldoc);//JSON格式解析//parseJson(xmlhttp.responseText);}}}//DOM解析XMLfunction 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.childNodes.childNodes.data;//data和nodeValue都可以var name_txt = city.childNodes.childNodes.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.id);var name_obj = document.createTextNode(json.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.id + "'>" + json.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 fzbtshy@163.com */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方式生成XMLprovinceXml= 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;}@Overridepublic 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 fzbtshy@163.com */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:'永州市'}] */publicString 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*/publicString 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> 
 
页: [1]
查看完整版本: 原生AJAX或jQuery实现二级联动选择以及解析XML和JSON数据格式