一、实现目标
首先会有一个存放中国行政区域数据的一个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资源文件的方法来自网络整理修改,后面的内容是项目中实际应用,现记以温之;
边系鞋带边思考人生.