- zhanghaidang
- 等级: 初级会员
- 性别:
- 文章: 26
- 积分: 40
- 来自: 武汉
|
想实现一个省市联动菜单,断断续续研究了好长时间,现在终于通过自己的努力实现了.
过程详解:
准备工作:
一个XML文件:
xml 代码
- <!---->xml version="1.0" encoding="GBK"?>
- <china>
- <province name="直辖市">
- <city>北京city>
- <city>上海city>
- <city>天津city>
- <city>重庆city>
- province>
- <province name="广东">
- <city>广州city>
- <city>珠海city>
- <city>深圳city>
- <city>东莞city>
- province>
- <province name="广西">
- <city>桂林city>
- <city>柳州city>
- <city>北海city>
- <city>南宁city>
- province>
- <province name="海南">
- <city>海口city>
- <city>三亚city>
- province>
- <province name="湖北">
- <city>武汉city>
- <city>鄂州city>
- <city>荆州city>
- <city>十堰city>
- province>
- <province name="湖南">
- <city>长沙city>
- <city>岳阳city>
- <city>常德city>
- <city>张家界city>
- province>
- <province name="浙江">
- <city>杭州city>
- <city>绍兴city>
- <city>宁波city>
- <city>台州city>
- province>
- <province name="辽宁">
- <city>沈阳city>
- <city>大连city>
- <city>抚顺city>
- <city>铁岭city>
- province>
- china>
用一个Java类来解析这个XML文件,我用的是JDOM,实现的功能为能够获取所有省份,和传入省份的集合(用于Jsp页面显示),可以获取相应的城市集合.
java 代码
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import org.jdom.Document;
- import org.jdom.Element;
- import org.jdom.JDOMException;
- import org.jdom.input.SAXBuilder;
- public class ReadXml {
- private Element root = null;
-
- public ReadXml() throws FileNotFoundException, JDOMException, IOException {
- super();
- SAXBuilder sb = new SAXBuilder();
- Document doc = sb.build(this.getClass().getResourceAsStream("/city.xml"));
- root = doc.getRootElement();
- }
-
- public List getProvince(){
- ArrayList provinceList = new ArrayList();
- List tempList = root.getChildren();
- for(int i=0; i
- Element province=(Element)tempList.get(i);
- provinceList.add(province.getAttributeValue("name"));
- }
- return provinceList;
- }
-
- public List getCity(String province){
- ArrayList cityList = new ArrayList();
- List provincetemplist = root.getChildren();
- for(int i=0; i
- Element provinceElement = (Element)provincetemplist.get(i);
- if((provinceElement.getAttributeValue("name")).equals(province)){
- List cityTempList = provinceElement.getChildren();
- for(int j=0; j
- Element cityElement = (Element)cityTempList.get(j);
- cityList.add(cityElement.getTextTrim());
- }
- }
- }
- return cityList;
- }
- }
准备工作完毕,建一个Struts工程
写一个Action,用来获取省份集合
java 代码
- public class GetProvinceAction extends Action {
-
- public ActionForward execute(ActionMapping mapping, ActionForm form,
- HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException, JDOMException, IOException {
- ReadXml rx = new ReadXml();
- List provinces = rx.getProvince();
- request.setAttribute("provinces", provinces);
- return mapping.findForward("success");
- }
- }
先通过此Action,然后再显示首页,这样省的下拉框里就有值了.
我先把Struts-Config.XML文件贴出来
xml 代码
- <form-beans>
- <form-bean name="selectForm" type="com.selectdemo.struts.form.SelectForm" />
- form-beans>
- <action-mappings>
-
- <action path="/getProvince" type="com.selectdemo.struts.action.GetProvinceAction">
- <forward name="success" path="/select.jsp"/>
- action>
-
- <action path="/select" scope="request" input="/select.jsp" name="selectForm"
- type="com.selectdemo.struts.action.SelectAction">
- <forward name="success" path="/getProvince.do" />
- action>
然后是显示的JSP页面
xml 代码
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
- <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
- <%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%>
-
- <html:html>
- <head>
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="cache-control" content="no-cache">
- <title>Insert title heretitle>
- head>
- <script type="text/javascript">
- var xmlHttp;
- // 创建xmlHttp;
- function createXMLHttpRequest(){
- if(window.ActiveXObject){
- xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
- }else if(window.XMLHttpRequest){
- xmlHttp = new XMLHttpRequest();
- }
- }
-
- // 删除城市选项
- function clearCityList(){
- var citys = document.getElementById("city");
- while(citys.childNodes.length > 0){
- citys.removeChild(citys.childNodes[0]);
- }
- }
-
- //选项省份时
- function selectProvince(){
- var province = document.getElementById("province").value;//获取省份值
-
- if(province == ""){ //如果为空,则清空城市选项
- clearCityList();
- var citySelect = document.getElementById("city"); //获取城市select组件
- var option = document.createElement("option");
- option.appendChild(document.createTextNode("请选择城市"));
- citySelect.appendChild(option);
- return ; //返回
- }
- //服务器处理地址,是一个Servlet
- var url = "http://localhost:8080/SelelctDemo/servlet/Linkage?province=" + encodeURIComponent(province) + "&ts=" + new Date().getTime();
- createXMLHttpRequest();//创建xmlHttp对象;
- xmlHttp.onreadystatechange = handleStateChange; //回调函数
- xmlHttp.open("GET",url,true);
- xmlHttp.send(null);
- }
-
- //回调函数
- function handleStateChange(){
- if(xmlHttp.readyState == 4){
- if(xmlHttp.status == 200){
- updateCitysList();
- }
- }
- }
-
- //页面更新城市集合函数
- function updateCitysList(){
- clearCityList();//首先删除先前的城市选项
- var citySelect = document.getElementById("city"); //获取城市select组件
- var results = xmlHttp.responseXML.getElementsByTagName("city");//获取Ajax返回的结果,city为返回的XML里的节点
- var option = null;
- for(var i=0; i<results.length; i++){
- option = document.createElement("option");
- option.appendChild(document.createTextNode(results[i].firstChild.nodeValue));
- citySelect.appendChild(option);
- }
- }
- script>
- <body>
- <html:form action="/select" method="post">
- <logic:present name="provinces" scope="request">
- <html:select property="province" styleId="province" onchange="selectProvince();">
- <html:option value="">请选择省份html:option>
- <html:options name="provinces" labelName="provinces" />
- html:select>
-
- <html:select property="city" styleId="city" style="width:90px">
- <html:option value="">请选择城市html:option>
- html:select>
- logic:present>
- <html:submit>html:submit>
- html:form>
- <br/>省份:
- <logic:present name="province" scope="request">
- <bean:write name="province" scope="request"/>
- logic:present>
- <br/>城市:
- <logic:present name="city" scope="request">
- <bean:write name="city" scope="request"/>
- logic:present>
- body>
- html:html>
-
下面是按处理Ajax的Servlet
java 代码
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.List;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.jdom.JDOMException;
- import com.selectdemo.tool.ReadXml;
- public class Linkage extends HttpServlet {
-
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- response.setContentType("text/html;charset=UTF-8");
- String province = request.getParameter("province");
- System.out.println(province);
- ReadXml rx;
- List citys = null;
- try {
- rx = new ReadXml();
- citys = rx.getCity(province);
- } catch (JDOMException e) {
- e.printStackTrace();
- }
- System.out.println(citys.size());
-
- StringBuffer results = new StringBuffer("<citys>");
- for(int i=0; i<citys.size(); i++){
- results.append("<city>");
- results.append(citys.get(i));
- results.append("</city>");
- }
- results.append("</citys>");
- response.setContentType("text/xml;");
- PrintWriter pw = response.getWriter();
- System.out.println(results.toString());
- pw.print(results.toString());
- pw.flush();
- pw.close();
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
- }
Servlet处理完后,返回到JSP页面,会传给JSP页面一个XML文档,以字符串的形式传过去的,JSP页面解析这个String,从而增加城市选项的下拉列表
点击submit后,用一个Action接收,看值传进来没有
java 代码
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.struts.action.Action;
- import org.apache.struts.action.ActionForm;
- import org.apache.struts.action.ActionForward;
- import org.apache.struts.action.ActionMapping;
- import com.selectdemo.struts.form.SelectForm;
-
- public class SelectAction extends Action {
-
- public ActionForward execute(ActionMapping mapping, ActionForm form,
- HttpServletRequest request, HttpServletResponse response) {
- response.setContentType("text/html;charset=UTF-8");
- SelectForm sf = (SelectForm)form;
- String province = sf.getProvince();
- System.out.println(province);
- String city = sf.getCity();
- System.out.println(city);
- request.setAttribute("province", province);
- request.setAttribute("city", city);
- return mapping.findForward("success");
- }
- }
这里,你会发现,传进来的值会是乱码,解决乱码我写了一个MyActionServlet
java 代码
- import org.apache.struts.action.ActionServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- public class MyActionServlet extends org.apache.struts.action.ActionServlet
- {
- protected void process(HttpServletRequest request, HttpServletResponse response)
- throws java.io.IOException, javax.servlet.ServletException
- {
- request.setCharacterEncoding("UTF-8");
- super.process(request, response);
- }
- }
好了,到这里后,就大功告成了.
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
返回顶楼 |
|
|
- lightround
- 等级: 初级会员
- 性别:
- 文章: 2
- 积分: 30
- 来自: 北京
|
To:zhanghaidang
看了你的代码,能不能交流一下,我目前在用Ajax,想体验一下Ajax的好处,请不吝赐教
谢谢
|
返回顶楼 |
|
|
- laowang_27hotmail.com
- 等级: 初级会员
- 性别:
- 文章: 9
- 积分: 30
- 来自: 西安
|
你确定把整个都贴出来了?
|
返回顶楼 |
|
|
- zhanghengfirst
- 等级: 初级会员
- 性别:
- 文章: 18
- 积分: 30
- 来自: 北京
|
没贴全吧,,
|
返回顶楼 |
|
|
- 迷失的人
- 等级: 初级会员
- 性别:
- 文章: 6
- 积分: 30
- 来自: 广州
|
我想问问,有必要用到struts吗?直接用AJAX还不行,你这个只是双组合,如果是三组合、四组合呢,还用struts吗?直接用AJAX吧,将你的xml文件加载到客户端处理就行了。这只是我个人认为而已。
|
返回顶楼 |
|
|
- 迷失的人
- 等级: 初级会员
- 性别:
- 文章: 6
- 积分: 30
- 来自: 广州
|
还有提醒一下楼主,请将js代码封装成类的形式吧,这样对人对自己都有好出的。
|
返回顶楼 |
|
|
- kellersoon
- 等级: 初级会员
- 性别:
- 文章: 9
- 积分: 30
- 来自: 杭州
|
少web.xml servlet用改後的 MyActionServlet
不錯!學習啦
不過我覺得沒必要用struts
個人看法
|
返回顶楼 |
|
|
- ice123456
- 等级: 初级会员
- 性别:
- 文章: 181
- 积分: 80
- 来自: 武汉
|
引用 for(int i=0; i
Element provinceElement = (Element)provincetemplist.get(i);
if((provinceElement.getAttributeValue("name")).equals(province)){//如果属性为传进来的名称
List cityTempList = provinceElement.getChildren();//获取子节点集合
for(int j=0; j//循环
Element cityElement = (Element)cityTempList.get(j);//当前城市节点
cityList.add(cityElement.getTextTrim());//增加城市到集合
}
}
}
如果你第一个值就查找出来,这不是在浪费资源???
直接用js读,不是更快??
|
返回顶楼 |
|
|