Java获取高德API行政区划数据存到数据库,维护到乡镇一级

1.申请高德行政区划API的key

2.pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hyd</groupId>
    <artifactId>area</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>area</name>e
    <description>获取高德api行政区划</description>

    <properties>
        <java.version>1.8</java.version>
        <mybatis.plus.version>3.4.1</mybatis.plus.version>
        <knife4j.version>1.9.6</knife4j.version>
        <validation.version>2.0.1.Final</validation.version>
        <fastjson.version>1.2.74</fastjson.version>
        <hutool.version>5.4.7</hutool.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <!--swagger-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>${knife4j.version}</version>
        </dependency>
        <!-- 阿里JSON解析器 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>${validation.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3.yml文件

# 数据库配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/AREA?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
# 获取行政区划信息
area:
  url: https://restapi.amap.com/v3/config/district
  key: 你申请的key

4.数据库结构

CREATE TABLE `t_area` (
  `ad_code` bigint(32) NOT NULL COMMENT '主键(区域编码)\r\n',
  `parent_code` varchar(32) DEFAULT NULL COMMENT '父级区域编码',
  `name_` varchar(64) DEFAULT NULL COMMENT '行政单位名称',
  `city_code` varchar(32) DEFAULT NULL COMMENT '城市编码',
  `type_` varchar(32) DEFAULT NULL COMMENT '行政单位类别 省 市 区/县 街道/乡镇',
  `center` varchar(64) DEFAULT NULL COMMENT '经度,纬度',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`ad_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

5.获取yml配置文件配置类

package com.hyd.area.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 获取yml配置文件信息
 * </p>
 *
 * @ClassName AreaConfig
 * @Date 2020/12/2 13:37
 * @Author hzy
 */
@Data
@Component
@ConfigurationProperties(prefix = "area")
public class AreaConfig {
    /**
     * 请求地址
     */
    private String url;

    /**
     * APIkey
     */
    private String key;
}

6.实体类

package com.hyd.area.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.hyd.area.base.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;

import java.util.List;

/**
 * <p>
 * (t_area)实体类
 * </p>
 *
 * @Classname Area
 * @Date 2020-12-01 09:59:38
 * @Author hzy
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Builder(toBuilder = true)
@TableName("t_area")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "(t_area)实体类", description = "(t_area)实体类")
public class Area extends BaseEntity<Long> {
    private static final Long serialVersionUID = -14216400471825395L;
   /**
     * 区域编码  街道没有独有的adCode,均继承父类(区县)的adCode
     */
    @TableField(value = "ad_code")
    @ApiModelProperty(value = "区域编码  街道没有独有的adCode,均继承父类(区县)的adCode", notes = "区域编码  街道没有独有的adCode,均继承父类(区县)的adCode")
    private String adCode;

    /**
     * 父级id
     */
    @TableField(value = "parent_code")
    @ApiModelProperty(value = "父级id", notes = "父级id")
    private String parentCode;

    /**
     * 名称
     */
    @TableField(value = "name_")
    @ApiModelProperty(value = "名称", notes = "名称")
    private String name;

    /**
     * 城市编码
     */
    @TableField(value = "city_code")
    @ApiModelProperty(value = "城市编码", notes = "城市编码")
    private String cityCode;

    /**
     * 等级  国家 省 市 区/县
     */
    @TableField(value = "type_")
    @ApiModelProperty(value = "等级  国家 省 市 区/县", notes = "等级  国家 省 市 区/县")
    private String level;


    /**
     * 经度,纬度
     */
    @TableField(value = "center")
    @ApiModelProperty(value = "经度,纬度", notes = "经度,纬度")
    private String center;

    /**
     * 子节点
     */
    @TableField(exist = false)
    private List<Area> districts;
}

7.httpUtil

package com.hyd.area.common;

import lombok.extern.slf4j.Slf4j;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;

/**
 * <p>
 * 通用http请求
 * </p>
 *
 * @ClassName HttpUtil
 * @Date 2020/12/1 10:08
 * @Author hzy
 */
@Slf4j
public class HttpUtil {
    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        return sendGet(url, param, Constants.UTF8);
    }

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url         发送请求的 URL
     * @param param       请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @param contentType 编码类型
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param, String contentType) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (ConnectException e) {
            log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
            log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
        } catch (IOException e) {
            log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
        } catch (Exception e) {
            log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception ex) {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }   
}

8.获取行政区划信息工具类

package com.hyd.area.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hyd.area.config.AreaConfig;
import com.hyd.area.entity.Area;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * 获取行政区划工具类
 * </p>
 *
 * @ClassName AreaUtils
 * @Date 2020/11/30 15:55
 * @Author hzy
 */
@Component
public class AreaUtils {

    /**
     * 获取配置信息
     */
    @Resource
    private AreaConfig areaConfig;

    /**
     * 获取行政区划方法
     *
     * @param param       规则:只支持单个关键词语搜索关键词支持:行政区名称、cityCode、adCode
     * @param subDistrict 规则:设置显示下级行政区级数(行政区级别包括:国家、省/直辖市、市、区/县4个级别)
     *                    <p>
     *                    可选值:0、1、2、3
     *                    <p>
     *                    0:不返回下级行政区;
     *                    <p>
     *                    1:返回下一级行政区;
     *                    <p>
     *                    2:返回下两级行政区;
     *                    <p>
     *                    3:返回下三级行政区;
     * @return list
     */
    public List<Area> getInfo(String param, String subDistrict) {
        String result = HttpUtil.sendGet(areaConfig.getUrl(), "keywords=" + param + "&subdistrict=" + subDistrict + "&key=" + areaConfig.getKey());
        JSONObject jsonObject = JSON.parseObject(result);
        String country = jsonObject.getString("districts");
        return JSON.parseArray(country, Area.class);
    }
}

9.controller,递归。

package com.hyd.area.controller;

import cn.hutool.core.util.StrUtil;
import com.hyd.area.common.AreaUtils;
import com.hyd.area.entity.Area;
import com.hyd.area.service.AreaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * (t_area_ultimate)服务实现层
 * </p>
 *
 * @ClassName AreaController
 * @Date 2020-12-01 09:59:38
 * @Author hzy
 */
@RestController
@RequestMapping("area")
@Api(value = "获取行政区划", tags = "获取行政区划数据")
@Slf4j
public class AreaController {
    /**
     * 服务对象
     */
    @Resource
    private AreaService areaService;

    @Resource
    private AreaUtils areaUtils;

    /**
     * 标识符
     */
    private static final String NONE = "[]";

    private static final String STREET = "street";

    private static final String PROVINCE = "province";

    /**
     * 只保存省级行政单位下3级的数据
     */
    @GetMapping(value = "/getActive")
    @ApiOperation(value = "只保存省级行政单位下3级的数据", notes = "只保存省级行政单位下3级的数据")
    public void getActive() {
        // 获取国家节点数据
        List<Area> countryList = areaUtils.getInfo("", "1");
        countryList.forEach(country -> {
            // 获取国家下面的所有省份
            List<Area> provinceList = country.getDistricts();
            // 排序
            provinceList = provinceList.stream().sorted(Comparator.comparing(Area::getAdCode)).collect(Collectors.toList());
            provinceList.forEach(province -> {
                List<Area> cityList = areaUtils.getInfo(province.getAdCode(), "3");
                recursion(cityList, province.getAdCode());
            });
        });
        log.info("数据拉取保存成功!");
    }

    /**
     * 递归保存数据
     *
     * @param parentList 父级行政单位数据
     */
    public void recursion(List<Area> parentList, String parentCode) {
        if (CollectionUtils.isEmpty(parentList)) {
            return;
        }
        // 对街道,乡镇adCode特殊处理
        for (int i = 0; i < parentList.size(); i++) {
            Area area = parentList.get(i);
            if (StrUtil.equals(NONE, area.getCityCode())) {
                area.setCityCode("");
            }
            if (StrUtil.equals(STREET, area.getLevel())) {
                Long streetId = Long.valueOf(area.getAdCode().concat(String.format("%02d", i + 1)));
                area.setAdCode(String.valueOf(streetId));
            }
        }
        parentList.forEach(child -> {
            // 设置父id
            if (StrUtil.equals(PROVINCE, child.getLevel())) {
                child.setParentCode(String.valueOf(0));
            } else {
                child.setParentCode(parentCode);
            }
            // 保存数据
            if (areaService.save(child)) {
                if (!CollectionUtils.isEmpty(child.getDistricts())) {
                    recursion(child.getDistricts(), child.getAdCode());
                }
            }
        });

    }
}


10.点我直接下载我弄好的数据。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐