今天学习了Ajax技术,刚刚做了一个省份-城市联动的Ajax应用示例。可能很多人都已经写过了,也是一个比较简单的例子,在这里分享出来大家共同学习交流一下。希望能给到那些像我一样的菜鸟程序员参考一点帮助吧!
效果截图:
省份-城市联动就是当你在省份下拉列表框选择一个省份的时候,旁边的城市下拉列表框就会动态地生成该省份对应的城市列表。如:省份是广东,则城市的下拉框对应显示广州、茂名、梅州等城市;省份是北京,城市的下拉列表框则显示海淀、朝阳等城市。因为我本人主要从事JavaEE的相关开发,因此这个小应用示例也就写专业一点啦!使用model2的两层架构。因为是一个小应用示例,因此没有跟数据库打交道,数据就都保存到内存中。
好了,我讲的废话太多了,下面开始叙述省份-城市联动的开发过程。
实施步骤:
- 编写后台service层。在三层架构中,层与层之间使用接口连接,因此要编写service接口。
- 编写后台web层的控制器servlet(省份的控制器和城市的控制器),主要负责加载后台省份和城市的数据,并将其传输到前台页面。
- 编写前台html静态页面,负责给用户显示数据。
- 编写javascript脚本程序,处理用户选择省份的请求操作。
整个应用的流程图:
(一)service层的接口代码
package cn.itcast.ajax.service; import java.util.List; public interface ProvinceCityService { /** * 返回省份数据集合 * @return */ List<String> loadProvince(); /** * 根据省份返回城市的集合 * @param province * @return */ List<String> loadCity(String province); }
实现接口中定义的功能
package cn.itcast.ajax.service.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import cn.itcast.ajax.service.ProvinceCityService; public class ProvinceCityServiceImpl implements ProvinceCityService { /* * 因为是一个省份与城市下拉的ajax小应用实例,因此不与数据库交道了,使用map存储数据 (non-Javadoc) * * @see cn.itcast.ajax.service.ProvinceService#loadProvince() */ private Map<String,List<String>> provinceMap = new HashMap<String,List<String>>(); String[] gdCity = new String[] { "广州","汕头","梅州","茂名" }; String[] bjCity = new String[] { "海淀","朝阳","中关村" }; public ProvinceCityServiceImpl() { provinceMap.put("广东",Arrays.asList(gdCity)); provinceMap.put("北京",Arrays.asList(bjCity)); } @Override public List<String> loadProvince() { List<String> provinces = new ArrayList<String>(); Set<String> keySet = provinceMap.keySet(); for (Iterator<String> iterator = keySet.iterator(); iterator.hasNext();) { String province = iterator.next(); provinces.add(province); } return provinces; } @Override public List<String> loadCity(String province) { return provinceMap.get(province); } }
(二)控制层Servlet代码
因为需要对省份和城市分开不同处理,所以使用ProvinceServlet和CityServlet两个servlet控制器
ProvinceServlet:
package cn.itcast.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 cn.itcast.ajax.service.ProvinceCityService; import cn.itcast.ajax.service.impl.ProvinceCityServiceImpl; /** * Servlet implementation class ProvinceServlet */ public class ProvinceServlet extends HttpServlet { private static final long serialVersionUID = 1L; private ProvinceCityService provinceService = new ProvinceCityServiceImpl(); protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { request.setCharacterEncoding("UTF-8"); List<String> provinces = provinceService.loadProvince(); StringBuffer sb = new StringBuffer(); sb.append("["); for (int i =0;i<provinces.size();i++) { String province = provinces.get(i); sb.append("\"").append(province).append("\""); // 如果i的值小于list的长度的时候就添加一个逗号,确保最后一个不会添加多一个逗号 if (i < provinces.size() - 1) { sb.append(","); } } sb.append("]"); response.setHeader("Content-Type","text/html; charset=UTF-8"); response.getWriter().println(sb.toString()); } protected void doPost(HttpServletRequest request,IOException { doGet(request,response); } public void testData() { List<String> provinces = provinceService.loadProvince(); StringBuffer sb = new StringBuffer(); sb.append("["); for (int i =0;i<provinces.size();i++) { String province = provinces.get(i); sb.append("\"").append(province); // 如果i的值小于list的长度的时候就添加一个逗号,"); } } sb.append("]"); System.out.println(sb.toString()); } }
CityServlet:
package cn.itcast.ajax.servlet; import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.itcast.ajax.service.ProvinceCityService; import cn.itcast.ajax.service.impl.ProvinceCityServiceImpl; /** * Servlet implementation class CityServlet */ public class CityServlet extends HttpServlet { private static final long serialVersionUID = 1L; private ProvinceCityService cityService = new ProvinceCityServiceImpl(); protected void doGet(HttpServletRequest request,IOException { String province = request.getParameter("province"); List<String> citys = cityService.loadCity(province); StringBuffer sb = new StringBuffer("["); for (int i = 0; i < citys.size(); i++) { sb.append("\"").append(citys.get(i)).append("\""); if (i < citys.size() - 1) { sb.append(","text/html; charset=UTF-8"); response.getWriter().println(sb.toString()); response.getWriter().close(); } protected void doPost(HttpServletRequest request,response); } }
(三)前台html静态页面province_city.html
这里要注意一点,省份的数据需要首先加载出来,添加到省份的下拉列表框中,因此在这个页面载入的时候就必须从后台加载数据出来。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>省份-城市下拉联动</title> <script type="text/javascript" src="province_city.js"></script> </head> <body> 请选择省份:<select id="province" onchange="provinceChange()"></select> 请选择城市:<select id="city"></select> </body> </html>
(四)javascript脚本程序province_city.js
// 初始化XMLHttpRequest对象 function createXmlHttpRequest() { var xmlhttp = null; try { // Firefox,Opera 8.0+,Safari xmlhttp = new XMLHttpRequest(); } catch (e) {// IE7.0以下的浏览器以ActiveX组件的方式来创建XMLHttpRequest对象 var MSXML = [ 'MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP' ]; for ( var i = 0; i < MSXML.length; i++) { try { xmlhttp = new ActiveXObject(MSXML[i]); break; } catch (e) { } } } // 返回对象 return xmlhttp; } window.onload = function() { loadProvinces(); }; // 加载省份数据 function loadProvinces() { var province = document.getElementById("province"); //alert("sdhgjf"); // 创建XMLHttpRequest对象 var xhr = createXmlHttpRequest(); // 发送请求 xhr.open("get","ProvinceServlet",true); xhr.send(null); // 接收服务器端传递回来的数据 xhr.onreadystatechange = function() { // 判断数据是否处理完全 if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) { var provinces = eval("(" + xhr.responseText + ")"); //alert(provinces); // 处理返回来的字符串 var s = "<option>请选择</option>"; for ( var i = 0; i < provinces.length; i++) { s+="<option>"+provinces[i]+"</option>"; } province.innerHTML = s; } }; } // 省份选择发生改变的时候的处理函数 function provinceChange() { // 获取当前选中的省份 var provinces = document.getElementById("province"); var province = provinces.options[provinces.selectedIndex].value; var city = document.getElementById("city"); //alert(province); var xhr = createXmlHttpRequest(); xhr.open("post","CityServlet",true); // 以post方式发送请求的时候需要设置请求的方式 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.send("province="+province); // 处理服务器端返回来的数据 xhr.onreadystatechange = function() { // 判断数据是否处理完全 if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) { var citys = eval("(" + xhr.responseText + ")"); //alert(provinces); // 处理返回来的字符串 var s = "<option>--</option>";// 创建一个option子元素 for ( var i = 0; i < citys.length; i++) {// 将返回来的城市数据添加到option元素中 s+="<option>"+citys[i]+"</option>"; } city.innerHTML = s; } }; }
因为这个小应用纯粹用于学习总结,因此写了比较多的注释,但是总体还算比较易于阅读的。
原文链接:https://www.f2er.com/ajax/166086.html