# chineseaddress **Repository Path**: memcacheon/address ## Basic Information - **Project Name**: chineseaddress - **Description**: 一、地址分词 识别地址字符串中的省市区县、街道、道路、小区、楼栋、单元、户室的等。 二、自定义词库加载 加载自定义词库,人工定向干预地址词库,提升地址分词和关联的准确性。 三、构建中文标准地址库 自动化的地址库工具,可以对低质量的地址分析、修正和建地址库。 四、普通地址关联标准地址算法 将非标准写法的地址统一关联到标准地址上。 五、快递地址自动解析省市区县以及名称电话和邮编等 六、自动补充行政区划 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: https://blog.csdn.net/u011024436?spm=1000.2115.3001.5343 - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 25 - **Created**: 2024-06-02 - **Last Updated**: 2024-06-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Addresstool简介 #### 目录 ``` Addresstool功能清单 1 一、 部署要求 1 二、 效率测试 2 三、 地址分词 2 四、 地址补全 3 五、 单条标准地址导入 3 六、 标准地址规范化 6 七、 地址关联算法 6 八、 标准批量地址导入 7 九、 标准地址导出 8 十、 大数据地址关联 8 十一、 API服务地址关联 12 十二、 地址质量评估 13 ``` #### 一、部署要求 1.服务器要求 由于算法很多数据都是直接加载到内存,服务器配置取决于楼盘表地址数据。大致对应关系如下: ``` 服务器内存 楼盘表地址数量级 城市级别 16G 100万以下 区及以下 32G 200万以下 区 64G 1000万 市 ``` 2.软件环境 场景 软件要求 其他 ``` 单机版 Java 8及以上 大数据集群 Hive 3.1.2及以上 Hadoop 3及以上 ``` | 场景 | 软件要求 | 其他 | |---|---|---| | 单机版 | Java 8及以上 | | | 大数据集群 | Hive 3.1.2及以上 | | | | | Hadoop 3及以上 | 3.数据依赖 ``` 数据项 现状 提供方 全国5级行政区划 已提前集成到算法 国家统计局爬取 全国道路部分名称 已提前集成到算法 网上下载 标准地址楼盘表 需初始化 自有/客户提供 ``` #### 二、效率测试 对核心功能进行速度测试(仅共参考,真实速度取决于硬件资源+楼盘表数据量+地址质量) ``` 功能 配置 楼盘表 次数 耗时 速度 地址分词 I7cpu16G内存笔记本 / 50万 6秒 8.3万/秒 地址关联算法 I7cpu16G内存笔记本 100万 10万 32秒 5000/秒 地址关联api服务 I7cpu16G内存笔记本 100万 5万 40秒 1250/秒 大数据 3台32核64G服务器集群 100万 800万 9分钟 1.5万/秒 ``` #### 三、地址分词 通过nlp分词识别出地址中的省市区县、乡镇、街道、aoi、楼栋、单元和户室。并且可以对三级行政区进行写法修正操作。 示例代码: ``` 1.import org.address.AddressTool; 2.import org.address.entity.Word; 3. 4.import java.util.List; 5. 6.public class AddressCutTest { 7.    public static void main(String[] args) { 8.        AddressTool ss = new AddressTool(); 9.        List words; 10.        //正常地址 11.        words = ss.cutAddress("湖北省武汉市汉阳区汉阳大道10号花果山5号楼1单元101室"); 12.        System.out.println(words); 13.        //城市名修正 14.        words = ss.cutAddress("湖北省武汉汉阳区汉阳大道10号花果山5栋1单元101户"); 15.        System.out.println(words); 16.        // 省份修正 城市修正 17.        words = ss.cutAddress("湖北武汉汉阳区汉阳大道10号花果山5号楼1单元101室"); 18.        System.out.println(words); 19.        // 城市修正 20.        words = ss.cutAddress("武汉汉阳区汉阳大道10号花果山5号楼1单元101室"); 21.        System.out.println(words); 22.    } 23.} 效果: 1.[{province:湖北省}, {city:武汉市}, {county:汉阳区}, {road:汉阳大道}, {road_no:10}, {aoi:花果山}, {building:5}, {unit:1}, {room:101}] 2.[{province:湖北省}, {city:武汉市}, {county:汉阳区}, {road:汉阳大道}, {road_no:10}, {aoi:花果山}, {building:5}, {unit:1}, {room:101}] 3.[{province:湖北省}, {city:武汉市}, {county:汉阳区}, {road:汉阳大道}, {road_no:10}, {aoi:花果山}, {building:5}, {unit:1}, {room:101}] 4.[{city:武汉市}, {county:汉阳区}, {road:汉阳大道}, {road_no:10}, {aoi:花果山}, {building:5}, {unit:1}, {room:101}] #### 四、地址补全 对于有些地址三级行政区缺失的,可以进行向上补全。例如地址中写江夏区,可以补充湖北省武汉市,如果地址中写武汉市,可以补充湖北省。 示例代码: 1.public class AddressCutTest { 2.    public static void main(String[] args) { 3.        AddressTool ss = new AddressTool(); 4.        System.out.println(ss.complete(ss.cutAddress("武汉市 汉阳永丰路 永丰乡政府小区"))); 5.        System.out.println(ss.complete(ss.cutAddress("上海市长宁区金钟路658弄5号楼5楼"))); 6.    } 7.} ``` 效果: ``` 1.[{province:湖北省}, {city:武汉市}, {county:汉阳区}, {road:永丰路}, {aoi:永丰乡政府小区}] 2.[{province:上海市}, {county:长宁区}, {road:金钟路}, {road_no:658}, {building:5}, {floor:5}] ``` #### 五、单条标准地址导入 将已经治理好的楼盘表数据逐条写入到内存,通过简单规范化治理,就可以进行关联操作。 代码示例: ``` 1.    public static void main(String[] args) throws Exception { 2. 3.//        AddressTool ss = new AddressTool("localhost",6379);  // 配置数据写入redis 4.        AddressTool ss = new AddressTool();  // 配置数据写入内存 5.        DataTable data = new DataTable(); 6. 7.        HashMap address5 = new HashMap<>(); 8.        address5.put("province","江苏省");; 9.        address5.put("city","南京市"); 10.        address5.put("county","江宁区"); 11.        address5.put("town","荡山街道"); 12.        address5.put("community","中前社区"); 13.        address5.put("aoi","秦淮绿洲"); 14.        address5.put("other_name","南京乾程塑胶模具"); 15.        address5.put("sub_aoi","北苑"); 16.        address5.put("road","宏运大道"); 17.        address5.put("road_no","2299"); 18.        address5.put("near_roads","天地大道#金山大道#花果山大道:99");  // 道路别名 19.        address5.put("building","9"); 20.        address5.put("unit","1"); 21.        address5.put("room","1001"); 22.        address5.put("id","5"); 23.        data.addAddressDic(address5); 24.        HashMap address6 = new HashMap<>(); 25.        address6.put("province","江苏省"); 26.        address6.put("city","南京市"); 27.        address6.put("county","江宁区"); 28.        address6.put("town","荡山街道"); 29.        address6.put("community","中前社区"); 30.        address6.put("aoi","秦淮绿洲"); 31.        address6.put("other_name","南京乾程塑胶模具"); 32.        address6.put("sub_aoi","北苑"); 33.        address6.put("road","宏运大道"); 34.        address6.put("road_no","2299"); 35.        address6.put("near_roads","天地大道#金山大道#花果山大道:99");  // 道路别名 36.        address6.put("building","9"); 37.        address6.put("unit","2"); 38.        address6.put("room","1001"); 39.        address6.put("id","6"); 40.        data.addAddressDic(address6); 41. 42.        // 标准地址库修复,比如用户只有户室级地址,此方法为用户补充楼栋级和aoi级地址,当然,如果用户有自己已经标准化好的地址库,可以省略此方法 43.        data.addressFix(); 44.        // 将加工好的地址库写入到addresstool中 45.        data.initData(ss); 46. 47. 48. 49.        // 万事俱备,我们可以进行地址关联啦 50.        System.out.println(ss.getStdAddress("江苏省南京市江宁区中前社区宏运大道2299号秦淮绿洲")); 51.        System.out.println(ss.getStdAddress("江苏省南京市江宁区中前社区金山大道2299号秦淮绿洲")); 52.        System.out.println(ss.getStdAddress("江苏省南京市江宁区中前社区金山大道9号秦淮绿洲")); 53.        System.out.println(ss.getStdAddress("花果山大道99号秦淮绿洲北苑9-1-1001")); 54.        System.out.println(ss.getStdAddress("花果山大道秦淮绿洲北苑9-1-1001")); 55.        System.out.println(ss.getStdAddress("花果山大道秦淮绿洲9-1-1001")); 56.        System.out.println(ss.getStdAddress("金山大道秦淮绿洲")); 57. 58.        ss.destroy(); 59.    } ``` 效果: ``` 1.{linkLevel=aoi, list=[{near_roads=天地大道#金山大道#花果山大道:99, address=江苏省南京市江宁区荡山街道中前社区宏运大道2299号秦淮绿洲, town=荡山街道, city=南京市, county=江宁区, community=中前社区, type=aoi, aoi_id=6_unit_sub_aoi, province=江苏省, road=宏运大道, road_no=2299, alias_aois=南京乾程塑胶模具, aoi=秦淮绿洲, id=6_unit_sub_aoi}], addressLevel=aoi} 2.{linkLevel=aoi, list=[{near_roads=天地大道#金山大道#花果山大道:99, address=江苏省南京市江宁区荡山街道中前社区宏运大道2299号秦淮绿洲, town=荡山街道, city=南京市, county=江宁区, community=中前社区, type=aoi, aoi_id=6_unit_sub_aoi, province=江苏省, road=宏运大道, road_no=2299, alias_aois=南京乾程塑胶模具, aoi=秦淮绿洲, id=6_unit_sub_aoi}], addressLevel=aoi} 3.{linkLevel=aoi, list=[{near_roads=天地大道#金山大道#花果山大道:99, address=江苏省南京市江宁区荡山街道中前社区宏运大道2299号秦淮绿洲, town=荡山街道, city=南京市, county=江宁区, community=中前社区, type=aoi, aoi_id=6_unit_sub_aoi, province=江苏省, road=宏运大道, road_no=2299, alias_aois=南京乾程塑胶模具, aoi=秦淮绿洲, id=6_unit_sub_aoi}], addressLevel=aoi} 4.{linkLevel=room, list=[{room_id=5, near_roads=天地大道#金山大道#花果山大道:99, building_id=5_bld, subaoi_id=6_unit_sub, address=江苏省南京市江宁区荡山街道中前社区宏运大道2299号秦淮绿洲北苑9栋1单元1001室, town=荡山街道, city=南京市, county=江宁区, community=中前社区, type=room, aoi_id=6_unit_sub_aoi, building=9, room=1001, unit=1, province=江苏省, road=宏运大道, road_no=2299, alias_aois=南京乾程塑胶模具, sub_aoi=北苑, aoi=秦淮绿洲, id=5, unit_id=5_unit}], addressLevel=room} 5.{linkLevel=room, list=[{room_id=5, near_roads=天地大道#金山大道#花果山大道:99, building_id=5_bld, subaoi_id=6_unit_sub, address=江苏省南京市江宁区荡山街道中前社区宏运大道2299号秦淮绿洲北苑9栋1单元1001室, town=荡山街道, city=南京市, county=江宁区, community=中前社区, type=room, aoi_id=6_unit_sub_aoi, building=9, room=1001, unit=1, province=江苏省, road=宏运大道, road_no=2299, alias_aois=南京乾程塑胶模具, sub_aoi=北苑, aoi=秦淮绿洲, id=5, unit_id=5_unit}], addressLevel=room} 6.{linkLevel=room, list=[{room_id=5, near_roads=天地大道#金山大道#花果山大道:99, building_id=5_bld, subaoi_id=6_unit_sub, address=江苏省南京市江宁区荡山街道中前社区宏运大道2299号秦淮绿洲北苑9栋1单元1001室, town=荡山街道, city=南京市, county=江宁区, community=中前社区, type=room, aoi_id=6_unit_sub_aoi, building=9, room=1001, unit=1, province=江苏省, road=宏运大道, road_no=2299, alias_aois=南京乾程塑胶模具, sub_aoi=北苑, aoi=秦淮绿洲, id=5, unit_id=5_unit}], addressLevel=aoi} 7.{linkLevel=aoi, list=[{near_roads=天地大道#金山大道#花果山大道:99, address=江苏省南京市江宁区荡山街道中前社区宏运大道2299号秦淮绿洲, town=荡山街道, city=南京市, county=江宁区, community=中前社区, type=aoi, aoi_id=6_unit_sub_aoi, province=江苏省, road=宏运大道, road_no=2299, alias_aois=南京乾程塑胶模具, aoi=秦淮绿洲, id=6_unit_sub_aoi}], addressLevel=aoi} ``` #### 六、标准地址规范化 对于已经有的标准地址,为了进一步提高地址质量,并且达到addresstool的可识别要求,需要进行简单的规范化处理。 示例代码: ``` 1.        AddressTool ss = new AddressTool();  // 配置数据写入内存 2.        DataTable data = new DataTable(); 3. 4.        // 此处省略原始标准地址导入操作(单条导入/批量导入) 5.        // 。。。导入代码 6. 7.        // 补全行3级政区 对于行政完整的地址无需此操作 8.        data.completion(); 9.        // 标准地址库修复,比如用户只有户室级地址,此方法为用户补充楼栋级和aoi级地址,当然,如果用户有自己已经标准化好的地址库,可以省略此方法 10.        data.addressFix(); 11.        // 将加工好的地址库写入到addresstool中 12.        data.initData(ss); ``` #### 七、地址关联算法 通过业务地址,关联到楼盘表中标准地址,有通用算法和带参数算法2中模式 通用算法,代码示例: ``` 1.        AddressTool ss = new AddressTool();  // 配置数据写入内存 2.        DataTable data = new DataTable(); 3. 4.        // 此处省略标准地址加载过程 5.        //。。。。 6.        // getStdAddress为地址关联方法 7.        StandardAddress res = ss.getStdAddress("江苏南京市汤山街道中前社区宏运大道2299号秦淮绿洲北苑9栋1单元1001室"); 8.        System.out.println(res); ``` 带参算法,ignore参数代表要忽略的地理要素,如加上town,community的话,城镇和社区将不会参与地址判断。 代码示例: ``` 1.        Map mp = new HashMap<>(); 2.        mp.put("ignore","town,community"); 3.        System.out.println(ss.getStdAddress("武汉市锦绣龙城")); 4.        System.out.println(ss.getStdAddress("湖北省武汉市江夏高新四路1号万科魅力之城")); 5.        System.out.println(ss.getStdAddress("湖北省武汉市江夏高新四路万科魅力之城")); 6.        System.out.println(ss.getStdAddress("武汉市万科魅力之城")); ``` #### 八、标准批量地址导入 通过csv导入标准地址,代码示例: ``` 1.    public static void main(String[] args) throws Exception { 2.        AddressTool ss = new AddressTool(); 3.        DataTable as = new DataTable(); 4.        as.loadFromCsv("D:\\","武汉.csv"); 5.        as.addressFix(); 6.        System.out.println("用户地址 读取完毕!!! "); 7.        as.initData(ss); 8.        System.out.println(ss.getStdAddress("武汉市锦绣龙城")); 9.        System.out.println(ss.getStdAddress("湖北省武汉市江夏高新四路1号万科魅力之城")); 10.        System.out.println(ss.getStdAddress("湖北省武汉市江夏高新四路万科魅力之城")); 11.        System.out.println(ss.getStdAddress("武汉市万科魅力之城")); 12.        // close方法销毁DataTable,释放部分内存 13.        as.close(); 14.    } ``` 通过json文件导入标准地址,代码示例: ``` 1.    public static void main(String[] args) throws Exception { 2.        AddressTool ss = new AddressTool(); 3.        DataTable as = new DataTable(); 4. 5.        as.loadFromJson("D:\\","wuhan.json"); 6.        System.out.println("用户地址 读取完毕!!! "); 7.        as.initData(ss); 8.   9.        System.out.println(ss.getStdAddress("武汉市锦绣龙城")); 10.        System.out.println(ss.getStdAddress("湖北省武汉市江夏高新四路1号万科魅力之城")); 11.        System.out.println(ss.getStdAddress("湖北省武汉市江夏高新四路万科魅力之城")); 12.        System.out.println(ss.getStdAddress("武汉市万科魅力之城")); 13.        as.close(); 14.    } ``` #### 九、标准地址导出 对于已经规范化后的地址,可以保存为json文件,下次使用时就不需要再次做规范化操作了。 ``` 1.    public static void main(String[] args) throws Exception { 2.        AddressTool ss = new AddressTool(); 3.        DataTable as = new DataTable(); 4.        as.loadFromCsv("D:\\","武汉.csv"); 5.        as.addressFix(); 6.        // 将标准地址保存为json文件 7.        as.saveAsJson("D:\\","wuhan.json"); 8.        as.close(); 9.    } ``` #### 十、大数据地址关联 将关联算法相关的(标准地址加载-数据初始化-地址关联)流程全部封装到大数据环境,赋予大数据地址关联的能力。 代码示例: ``` 1.public class AddressLink extends GenericUDF { 2.    private PrimitiveObjectInspector addressIO; 3.    private static AddressTool addressTool; 4. 5.    private String bld(String building){ 6.        if(building!=null&&!building.isEmpty() ){ 7.            if(building.endsWith("栋")||building.endsWith("幢")){ 8.                return building.substring(0,building.length()-1); 9.            }else if(building.endsWith("号楼")){ 10.                return building.substring(0,building.length()-2); 11.            } 12.        } 13. 14.        return building; 15.    } 16. 17.    private String unit(String unit){ 18.        if(unit!=null&&!unit.isEmpty() ){ 19.            if(unit.endsWith("单元")){ 20.                return unit.substring(0,unit.length()-2); 21.            } 22.        } 23. 24.        return unit; 25.    } 26. 27.    private String room(String room){ 28.        if(room!=null&&!room.isEmpty() ){ 29.            if(room.endsWith("室")||room.endsWith("户")){ 30.                return room.substring(0,room.length()-1); 31.            } 32.        } 33. 34.        return room; 35.    } 36. 37.    @Override 38.    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { 39.        if (arguments[0] instanceof ObjectInspector) { 40.            addressIO = (PrimitiveObjectInspector) arguments[0]; 41.        }else{ 42.            throw new UDFArgumentLengthException("The function GetMapValue accepts  1 argument. simple: GetSqName(sq_name)"); 43.        } 44.        addressTool = new AddressTool(); 45.        DataTable data = new DataTable(); 46.        try{ 47.            // 数据源无限制,可以使用任何数据库作为标准地址存储工具,本项目以postgres为例 48.            //注册Driver 49.            String driver = "org.postgresql.Driver";//prop.getProperty("driver"); 50.            String url = "jdbc:postgresql://*****:5432/postgres";//prop.getProperty("url"); 51.            String username = "******";//prop.getProperty("user"); 52.            String password = "******";//prop.getProperty("password"); 53.            Class.forName(driver); 54.            Connection connection = DriverManager.getConnection(url, username, password); 55.            Statement statement = connection.createStatement(); 56. 57.            // 数据初始化 58.            ResultSet res = statement.executeQuery("select id,province,city,county,town,community,road,road_no,aoi,sub_aoi,building,unit,room,address from st_address order by aoi,road,road_no"); 59.            int cnt = 0; 60.            while (res.next()) { 61.                HashMap mp = new HashMap<>(); 62.                if(res.getString("id")!=null&& !Objects.equals(res.getString("id"), "")){mp.put("id",res.getString("id"));} 63.                if(res.getString("province")!=null&& !Objects.equals(res.getString("province"), "")){mp.put("province",res.getString("province"));} 64.                if(res.getString("city")!=null&& !Objects.equals(res.getString("city"), "")){mp.put("city",res.getString("city"));} 65.                if(res.getString("county")!=null&& !Objects.equals(res.getString("county"), "")){mp.put("county",res.getString("county"));} 66.                if(res.getString("town")!=null&& !Objects.equals(res.getString("town"), "")){mp.put("town",res.getString("town"));} 67.                if(res.getString("community")!=null&& !Objects.equals(res.getString("community"), "")){mp.put("community",res.getString("community"));} 68.                if(res.getString("road")!=null&& !Objects.equals(res.getString("road"), "")){mp.put("road",res.getString("road"));} 69.                if(res.getString("road_no")!=null&& !Objects.equals(res.getString("road_no"), "")){mp.put("road_no",res.getString("road_no"));} 70.                if(res.getString("aoi")!=null&& !Objects.equals(res.getString("aoi"), "")){mp.put("aoi",res.getString("aoi"));} 71.                if(res.getString("sub_aoi")!=null&& !Objects.equals(res.getString("sub_aoi"), "")){mp.put("sub_aoi",res.getString("sub_aoi"));} 72.                if(res.getString("building")!=null&& !Objects.equals(res.getString("building"), "")){mp.put("building",bld(res.getString("building")));} 73.                if(res.getString("unit")!=null&& !Objects.equals(res.getString("unit"), "")){mp.put("unit",unit(res.getString("unit")));} 74.                if(res.getString("room")!=null&& !Objects.equals(res.getString("room"), "")){mp.put("room",room(res.getString("room")));} 75.                if(res.getString("com/address")!=null&& !Objects.equals(res.getString("com/address"), "")){mp.put("com/address",res.getString("com/address"));} 76.                data.addAddressDic(mp); 77.                cnt = cnt + 1; 78.            } 79. 80.            //标准数据地址数据加载到addresstool 81.            data.initData(addressTool); 82.            data = null; 83.            statement.close(); 84.            connection.close(); 85. 86.        } catch (Exception throwables) { 87.            throwables.printStackTrace(); 88.        } 89. 90.        return ObjectInspectorFactory.getStandardMapObjectInspector( 91.                PrimitiveObjectInspectorFactory.javaStringObjectInspector, 92.                PrimitiveObjectInspectorFactory.javaStringObjectInspector); 93.    } 94. 95.    @Override 96.    public Object evaluate(DeferredObject[] arguments) throws HiveException { 97.        if(arguments[0].get()==null){ 98.            return null; 99.        } 100.        String address =  PrimitiveObjectInspectorUtils.getString(arguments[0].get(), this.addressIO); 101.        // 中文地址中的异常字符预处理 102.        while(address.contains(" ")){address = address.replace(" ","");} 103.        while(address.contains("--")){address = address.replace("--","-");} 104.        while(address.contains("——")){address = address.replace("——","-");} 105.        while(address.contains("- ")){address = address.replace("- ","-");} 106.        while(address.contains(" -")){address = address.replace(" -","-");} 107.        while(address.contains("— ")){address = address.replace("— ","-");} 108.        while(address.contains(" —")){address = address.replace(" —","-");} 109. 110.        // 地址关联 111.        StandardAddress stdAddress = addressTool.getStdAddress(address); 112.        Map result = stdAddress.getStdAddress(); 113.        // 地址级别判断 114.        if(stdAddress.addressLevel!=null&& !stdAddress.addressLevel.equals("")){ 115.            result.put("addressLevel",stdAddress.addressLevel); 116.        }else{ 117.            result.put("addressLevel","未知"); 118.        } 119. 120.        // 地址关联级别判断 121.        if(stdAddress.linkLevel!=null&& !stdAddress.linkLevel.equals("")){ 122.            result.put("linkLevel",stdAddress.linkLevel); 123.        }else{ 124.            result.put("linkLevel","未关联"); 125.        } 126.        return result; 127.    } 128. 129.    @Override 130.    public String getDisplayString(String[] children) { 131.        return "Address(" + children[0] + ")"; 132.    } 133. 134.} ``` #### 十一、API服务地址关联 将地址关联以api服务的形式发布 代码示例: ``` 1.public class AddressServer { 2.    static AddressTool ss = new AddressTool(); 3.//    static AddressTool ss = new AddressTool("localhost",6379); 4.    static DataTable as = new DataTable(); 5.    static Gson gson = new Gson(); 6. 7.    public static void main(String[] args) throws Exception { 8.        as.loadFromJson("D:\\","address2.json"); 9. 10.        System.out.println("用户地址 读取完毕!!! "); 11.        as.initData(ss); 12. 13.        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0); 14.        server.createContext("/standard", new MyHandler()); 15.        server.createContext("/test", new MyHandler2()); 16.        server.setExecutor(null); 17.        System.out.println("Starting server on port: 8000"); 18.        server.start(); 19.    } 20. 21.    static class MyHandler implements HttpHandler { 22.        public void handle(HttpExchange t) throws IOException { 23.            String response = "{\"response\":\"Hello World\"}"; 24. 25.            String parmsStr = t.getRequestURI().getQuery(); 26.            if(!parmsStr.isEmpty()){ 27.                String[] parms = parmsStr.split("&"); 28.                if(parms.length>0){ 29.                    HashMap keys = new HashMap<>(); 30.                    for (String urlKey:parms){ 31.                        if(urlKey.contains("=")){ 32.                            String[] kv = urlKey.split("="); 33.                            keys.put(kv[0].toLowerCase(),kv[1]); 34.                        } 35.                    } 36.                    if(keys.containsKey("address")){ 37.                        StandardAddress resp = ss.getStdAddress(keys.get("address")); 38. 39.                        if(resp.getAddress()!=null&& !resp.getAddress().isEmpty()){ 40.                            String addressJson; 41.                            ArrayList addrs = new ArrayList<>(); 42.                            int i = 1; 43.                            for(Map.Entry> mp:resp.getAddress().entrySet()){ 44.                                addressJson = gson.toJson(mp.getValue()); 45.                                addrs.add(addressJson); 46.                            } 47.                            String mapJson =  gson.toJson(addrs); 48.                            response = mapJson; 49.                        } 50. 51.                    } 52.                } 53.            } 54. 55.//            System.out.println(t.getRequestURI().getQuery()); 56. 57.            t.getResponseHeaders().set("Content-Type", "application/json"); 58.//            t.getResponseHeaders().set("Content-Type", "text/html;charset=utf-8"); 59.            t.sendResponseHeaders(200, 0); 60.            OutputStream os = t.getResponseBody(); 61.            byte[] b = response.getBytes(); 62.            for (int i = 0; i < b.length; i++) { 63.                os.write(b[i]); 64.            } 65.            os.close(); 66.        } 67.    } 68.} ``` #### 十二、地址质量评估 暂时未开发。