java解析中国行政区域并在页面显示实现动态逐级筛选
一、实现目标
首先会有一个存放中国行政区域数据的一个txt文件,用java读取并解析出来,并在页面上通过下拉框的形式展示出来。实现效果如下图,当选择完省份后,在选择该省份下的城市,然后在选择该城市下的县区这样逐级显示:
二、代码实现:
1. 先创建一个javaBean,用来存放基本数据;
1 public class Area { 2 private String code ;//行政编码 3 private String name;//名称 4 private int level;//行政级别 0:省/直辖市 1:地级市 2:县级市 5 private String parentCode;//上一级的行政区划代码 6 7 public Area() { 8 super(); 9 } 10 11 public Area(String code, String name, int level, String parentCode) { 12 super(); 13 this.code = code; 14 this.name = name; 15 this.level = level; 16 this.parentCode = parentCode; 17 } 18 19 public String getCode() { 20 return code; 21 } 22 23 public void setCode(String code) { 24 this.code = code; 25 } 26 27 public String getName() { 28 return name; 29 } 30 31 public void setName(String name) { 32 this.name = name; 33 } 34 35 public int getLevel() { 36 return level; 37 } 38 39 public void setLevel(int level) { 40 this.level = level; 41 } 42 43 public String getParentCode() { 44 return parentCode; 45 } 46 47 public void setParentCode(String parentCode) { 48 this.parentCode = parentCode; 49 } 50 51 public String toString(){ 52 return "行政编码:"+this.getCode()+"\t名称:"+this.getName()+"\t行政级别:"+ 53 this.getLevel()+"\t上一级的行政区划代码:" +this.getParentCode(); 54 } 55 }
2. 然后创建一个读取txt资源文件的工具类;
1 import java.io.BufferedReader; 2 import java.io.File; 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.util.ArrayList; 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map; 10 11 import com.***.Area; 12 13 public class ReadAreaUtil { 14 15 public List<Area> provinceList = new ArrayList<Area>(); 16 public List<Area> townList = new ArrayList<Area>(); 17 public List<Area> countyList = new ArrayList<Area>(); 18 19 public Map<String,List<Area>> getAreaData(String path){ 20 ReadAllArea(path); 21 Map<String,List<Area>> result = new HashMap<String,List<Area>>(); 22 result.put("provinceList", provinceList); 23 result.put("townList", townList); 24 result.put("countyList", countyList.subList(1, countyList.size())); //去掉表头 25 26 return result ; 27 } 28 29 public void ReadAllArea(String path){ 30 String line = null; 31 BufferedReader reader = null; 32 File file = new File(path); 33 34 String cityCode=""; 35 String countyCode=""; 36 try { 37 FileReader in = new FileReader(file); 38 reader = new BufferedReader(in); 39 //读取文件的每一行 40 while((line = reader.readLine())!=null){ 41 String[] data = cutString(line); 42 43 //处理读取的文件记录 44 if(isProvince(data[0])){ 45 cityCode = data[0]; 46 Area area = new Area(data[0], data[1], 0, "0"); 47 provinceList.add(area); 48 }else if(isTown(data[0])){ 49 countyCode =data[0]; 50 Area area = new Area(data[0], data[1], 1, cityCode); 51 townList.add(area); 52 }else{ 53 Area area = new Area(data[0], data[1], 2, countyCode); 54 countyList.add(area); 55 } 56 } 57 } catch (FileNotFoundException e) { 58 e.printStackTrace(); 59 } catch (IOException e) { 60 e.printStackTrace(); 61 }finally{ 62 try { 63 reader.close(); 64 } catch (IOException e) { 65 e.printStackTrace(); 66 } 67 } 68 } 69 70 //字符分割 71 public String[] cutString(String line){ 72 String code=""; 73 String name=""; 74 code = line.substring(0, 6); 75 String lastStr = line.substring(7, line.length()); 76 name = lastStr.substring(0, lastStr.indexOf("\t")); 77 String[] result = new String []{code,name}; 78 return result; 79 } 80 81 //判断是否省或者直辖市 82 public boolean isProvince(String code){ 83 String last = code.substring(2); 84 if("0000".equalsIgnoreCase(last)){ 85 return true; 86 } 87 return false; 88 } 89 //判断是否地级市 90 public boolean isTown(String code){ 91 String last = code.substring(4); 92 if("00".equalsIgnoreCase(last)){ 93 return true; 94 } 95 return false; 96 } 97 98 }
3. 改项目使用了struts2,在action的方法中调用即可:
1 //读txt数据... 2 String path = ServletActionContext.getServletContext().getRealPath("/2015Area.txt"); 3 Map<String,List<Area>> area = new ReadAreaUtil().getAreaData(path); 4 List<Area> provinceList = area.get("provinceList"); 5 ServletActionContext.getRequest().setAttribute("prlist", provinceList);
4. JSP页面上的html,第一个select是直接遍历的,但是后面两个就要根据前面select选中的来动态显示了,这里需要用到jQuery的Ajax;
1 <div id="areaDiv" > 2 <a >省份: 3 <select id="sel_province" name="" > 4 <option value="-1" >-请选择-</option> 5 <c:forEach var="pro" items="${prlist }"> 6 <option value="${pro.code }" >${pro.name }</option> 7 </c:forEach> 8 </select> 9 </a> 10 <a class="wsy_f14">城市/区: 11 <select id="sel_town" name="" > 12 <option value="-1" >-----</option> 13 </select> 14 </a> 15 <a class="wsy_f14">县级: 16 <select id="sel_county" name="" > 17 <option value="-1" >-----</option> 18 </select> 19 </a> 20 </div>
jQuery 代码,select标签变化时触发函数并发送post请求数据;
1 $(document).ready(function(){ 2 $('#sel_province').change(function(){ 3 var code = $(this).children('option:selected').val();//selected的值 4 $.post("${basePath}ajax/filterArea.action", 5 { 6 parentCode:code, 7 areaType:1//0省,1市,2县 8 }, 9 function(data){ 10 $("#sel_town").html(data); 11 }); 12 }); 13 14 $('#sel_town').change(function(){ 15 var code = $(this).children('option:selected').val();//selected的值 16 $.post("${basePath}ajax/filterArea.action", 17 { 18 parentCode:code, 19 areaType:2//0省,1市,2县 20 }, 21 function(data){ 22 $("#sel_county").html(data); 23 }); 24 }); 25 });
5. struts如何处理Ajax请求,专门写一个action用于处理ajax请求;
strut.xml:
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE struts PUBLIC 3 "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" 4 "http://struts.apache.org/dtds/struts-2.1.dtd"> 5 <struts> 6 <package name="ajax" namespace="/ajax" extends="json-default"> 7 <action name="filterArea" method="filterArea" class="com.llw.action.AjaxFilter"></action> 8 </package> 9 </struts>
action:
1 public class AjaxFilter extends ActionSupport { 2 3 //行政区域过滤 4 private String parentCode ; 5 private int areaType ; 6 public String getParentCode() { 7 return parentCode; 8 } 9 public void setParentCode(String parentCode) { 10 this.parentCode = parentCode; 11 } 12 public int getAreaType() { 13 return areaType; 14 } 15 public void setAreaType(int areaType) { 16 this.areaType = areaType; 17 } 18 19 public void filterArea(){ 20 String htmlStr = "<option value=\"-1\">-请选择-</option>" ; 21 22 String path = ServletActionContext.getServletContext().getRealPath("/2015Area.txt"); 23 Map<String,List<Area>> area = new ReadAreaUtil().getAreaData(path); 24 List<Area> areaList = null ; 25 if(areaType==1){ //0省,1市,2县 26 areaList = area.get("townList"); 27 }else if(areaType==2){ 28 areaList = area.get("countyList"); 29 } 30 if(areaList!=null && areaList.size()>0 && parentCode!=null){ 31 for(Area a : areaList){ 32 if(parentCode.equals(a.getParentCode())){ 33 htmlStr += "<option value=\""+a.getCode()+"\">"+a.getName()+"</option>" ; 34 } 35 } 36 } 37 38 // System.out.println("xxxxx"+htmlStr); 39 HttpServletResponse response = ServletActionContext.getResponse(); 40 PrintWriter writer = null; 41 try { 42 writer = response.getWriter(); 43 } catch (IOException e) { 44 e.printStackTrace(); 45 } 46 writer.print(htmlStr); 47 writer.flush(); 48 writer.close(); 49 } 50 51 }
三、总结:以上基本完成了需要的效果,用java读取txt资源文件,并封装到List里面,上面代码中把不同级别的数据放到不同的list里了,也可以放到同一个list里面,这个根据自己需要可以去修改;然后是通过Ajax方式动态逐级显示select展示的内容;并演示了strut中如何处理ajax请求。上面展示了其中一种strut处理ajax请求的方式,还有另外一中方式,跟普通action的原理类似,就是通过action里定义的成员变量,JS里的回调函数访问这些成员变量;
这里贴一下第二种方式的使用例子:
strut.xml: <action name="testAjax" class="com.crm.action.Ajaxcustomer" method="sayHello"> <result type="json" name="success"></result> </action> action: public class AjaxFilter extends ActionSupport { private int type; private String phone; private Map<String,Object> map ; //…get/set方法这里省略 public String sayHello(){ map = new HashMap<String, Object>(); map.put("aaa", "abc"); return SUCCESS; } } JS: function test(){ $.post("ajax/testAjax.action",//请求目标 { type:1, phone:$("#phone").val() }, function(data) {//回调函数 alert(data.map.aaa); $("#lia1").html(data.map.paramNum);//设置页面标签值 }); }
四、说明:以上java读取txt资源文件的方法来自网络整理修改,后面的内容是项目中实际应用,现记以温之;
边系鞋带边思考人生.