获取省市区数据的API调用(百度地图)
目录1.创建API Key2.创建类(1)BaiduUtil工具类(2) BaiduMapVO (值对象类)(3) SysAreaMapper (数据访问层)(4) AreaSyncUtil (同步工具类)3.调用关系图执行流程说明1.创建API Key来到百度地图开放平台登录之后点击创建应用控制台 | 百度地图开放平台https://lbsyun.baidu.com/apiconsole/key名字随便填就行选择服务端请求校验方式选择sn校验方式2.创建类(1)BaiduUtil工具类作用封装百度地图API的调用逻辑主要功能构造API请求参数计算SN签名安全认证发送HTTP请求获取地区数据解析JSON响应并转换为BaiduMapVO对象核心方法requestGetSN()- 执行API调用并返回地区数据列表package com.qcby.util; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.convert.Convert; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.qcby.VO.BaiduMapVO; import lombok.extern.slf4j.Slf4j; import org.springframework.web.util.UriUtils; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.security.NoSuchAlgorithmException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; Slf4j public class BaiduMapUtil { // 用户服务访问密钥 public static String AK ak; // 用于生成请求url public static String SK sk; public static String URL https://api.map.baidu.com/api_region_search/v1/?; public static void main(String[] args) throws Exception { BaiduMapUtil snCal new BaiduMapUtil(); Map paramsMap new LinkedHashMapString, String(); // paramsMap.put(keyword, 石家庄市); paramsMap.put(keyword, 中国); paramsMap.put(sub_admin, 4); paramsMap.put(extensions_code, 1); System.out.println(JSONUtil.toJsonStr(snCal.requestGetSN(paramsMap))); } public static ListBaiduMapVO requestGetSN(MapString, String param) throws Exception { param.put(ak, AK); param.put(sn, caculateSn(param)); return requestGetSN(URL, param); } /** * 选择了ak使用SN校验 * 根据您选择的AK已为您生成调用代码 * 检测您当前的AK设置了sn检验本示例中已为您生成sn计算代码 * param strUrl * param param * throws Exception */ public static ListBaiduMapVO requestGetSN(String strUrl, MapString, String param) throws Exception { if (strUrl null || strUrl.length() 0 || param null || param.size() 0) { return null; } StringBuffer queryString new StringBuffer(); queryString.append(strUrl); for (Map.Entry?, ? pair : param.entrySet()) { queryString.append(pair.getKey() ); // 第一种方式使用的 jdk 自带的转码方式 第二种方式使用的 spring 的转码方法 两种均可 // queryString.append(URLEncoder.encode((String) pair.getValue(), UTF-8).replace(, %20) ); queryString.append(UriUtils.encode((String) pair.getValue(), UTF-8) ); } if (queryString.length() 0) { queryString.deleteCharAt(queryString.length() - 1); } URL url new URL(queryString.toString()); log.info(请求百度地区url:{},queryString); URLConnection httpConnection url.openConnection(); httpConnection.connect(); InputStreamReader isr new InputStreamReader(httpConnection.getInputStream()); BufferedReader reader new BufferedReader(isr); StringBuffer buffer new StringBuffer(); String line; while ((line reader.readLine()) ! null) { buffer.append(line); } reader.close(); isr.close(); JSONObject jsonObject JSONUtil.parseObj(buffer.toString()); Object status jsonObject.get(status); if (status null || Convert.toInt(status)!0) { log.info(获取百度地区失败:{},buffer); return null; } JSONArray districts jsonObject.getJSONArray(districts); return BeanUtil.copyToList(districts, BaiduMapVO.class); } public static String caculateSn(Map paramsMap) throws UnsupportedEncodingException, NoSuchAlgorithmException { BaiduMapUtil snCal new BaiduMapUtil(); // 计算sn跟参数对出现顺序有关get请求请使用LinkedHashMap保存key,value该方法根据key的插入顺序排序post请使用TreeMap保存key,value该方法会自动将key按照字母a-z顺序排序。 // 所以get请求可自定义参数顺序sn参数必须在最后发送请求但是post请求必须按照字母a-z顺序填充bodysn参数必须在最后。 // 以get请求为例http://api.map.baidu.com/geocoder/v2/?address百度大厦outputjsonakyourakparamsMap中先放入address再放output然后放ak放入顺序必须跟get请求中对应参数的出现顺序保持一致。 //paramsMap // 调用下面的toQueryString方法对LinkedHashMap内所有value作utf8编码拼接返回结果address%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6outputjsonakyourak String paramsStr snCal.toQueryString(paramsMap); // 对paramsStr前面拼接上/geocoder/v2/?后面直接拼接yoursk得到/geocoder/v2/?address%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6outputjsonakyourakyoursk String wholeStr new String(/api_region_search/v1/? paramsStr SK); System.out.println(wholeStr); // 对上面wholeStr再作utf8编码 String tempStr URLEncoder.encode(wholeStr, UTF-8); // 调用下面的MD5方法得到最后的sn签名 String sn snCal.MD5(tempStr); System.out.println(sn); return sn; } // 对Map内所有value作utf8编码拼接返回结果 public String toQueryString(Map?, ? data) throws UnsupportedEncodingException { StringBuffer queryString new StringBuffer(); for (Map.Entry?, ? pair : data.entrySet()) { queryString.append(pair.getKey() ); // 第一种方式使用的 jdk 自带的转码方式 第二种方式使用的 spring 的转码方法 两种均可 // queryString.append(URLEncoder.encode((String) pair.getValue(), UTF-8).replace(, %20) ); queryString.append(UriUtils.encode((String) pair.getValue(), UTF-8) ); } if (queryString.length() 0) { queryString.deleteCharAt(queryString.length() - 1); } return queryString.toString(); } // 来自stackoverflow的MD5计算方法调用了MessageDigest库函数并把byte数组结果转换成16进制 public String MD5(String md5) { try { java.security.MessageDigest md java.security.MessageDigest .getInstance(MD5); byte[] array md.digest(md5.getBytes()); StringBuffer sb new StringBuffer(); for (int i 0; i array.length; i) { sb.append(Integer.toHexString((array[i] 0xFF) | 0x100) .substring(1, 3)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { } return null; } }(2) BaiduMapVO(值对象类)作用百度地图API返回数据的实体类用于接收API响应数据属性code地区编码name地区名称level地区层级country/province/city/districtdistricts子地区列表支持递归嵌套package com.qcby.VO; import lombok.Data; import java.util.List; Data public class BaiduMapVO { private String code; private String name; private String level; private ListBaiduMapVO districts; }(3)SysAreaMapper(数据访问层)作用MyBatis-Plus的Mapper接口负责数据库操作主要功能继承BaseMapper提供基础的CRUD方法自定义查询方法如按层级查询、按父级ID查询等对应表sys_area系统地区表package com.qcby.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.qcby.VO.SysArea; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; Mapper public interface SysAreaMapper extends BaseMapperSysArea { /** * 查询所有省份 (level 1) */ Select(SELECT * FROM sys_area WHERE level 1 ORDER BY area_id) ListSysArea selectProvinces(); /** * 根据父级ID查询子区域 */ Select(SELECT * FROM sys_area WHERE parent_id #{parentId} ORDER BY area_id) ListSysArea selectByParentId(String parentId); /** * 查询所有区域按层级和ID排序 */ Select(SELECT * FROM sys_area ORDER BY level, area_id) ListSysArea selectAll(); /** * 根据层级查询 */ Select(SELECT * FROM sys_area WHERE level #{level} ORDER BY area_id) ListSysArea selectByLevel(Integer level); /** * 查询国家 (level 0) */ Select(SELECT * FROM sys_area WHERE level 0) ListSysArea selectCountry(); }(4)AreaSyncUtil(同步工具类)作用核心的业务逻辑类负责将百度API数据同步到数据库主要功能启动Spring容器调用百度API获取数据清空原有数据递归处理地区层级关系批量保存到数据库package com.qcby.util; import com.qcby.Application; import com.qcby.VO.BaiduMapVO; import com.qcby.VO.SysArea; import com.qcby.mapper.SysAreaMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.context.ApplicationContext; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * 地区数据同步工具类 * 可以直接运行main方法执行同步 * * 使用方法 * 1. 在IDE中直接运行此类 * 2. 或者在命令行中执行java -cp your-app.jar com.qcby.util.AreaSyncUtil */ Slf4j public class AreaSyncUtil { public static void main(String[] args) { // 启动Spring容器 ApplicationContext context SpringApplication.run(Application.class, args); // 获取Mapper SysAreaMapper areaMapper context.getBean(SysAreaMapper.class); // 执行同步 syncArea(areaMapper); // 同步完成后退出 SpringApplication.exit(context, () - 0); System.exit(0); } public static void syncArea(SysAreaMapper areaMapper) { try { log.info(开始同步百度地区数据...); // 构建请求参数 MapString, String params new LinkedHashMap(); params.put(keyword, 中国); params.put(sub_admin, 4); params.put(extensions_code, 1); // 调用百度API获取地区数据 ListBaiduMapVO baiduMapVOList BaiduMapUtil.requestGetSN(params); if (baiduMapVOList null || baiduMapVOList.isEmpty()) { log.error(获取百度地区数据失败); return; } // 清空现有数据 areaMapper.delete(null); log.info(已清空现有地区数据); // 递归处理并保存地区数据 ListSysArea areaList new ArrayList(); for (BaiduMapVO baiduMapVO : baiduMapVOList) { processArea(null, baiduMapVO, areaList); } // 批量保存到数据库 if (!areaList.isEmpty()) { for (SysArea area : areaList) { areaMapper.insert(area); } log.info(成功同步 {} 条地区数据, areaList.size()); } } catch (Exception e) { log.error(同步地区数据异常: {}, e.getMessage(), e); } } private static void processArea(String parentId, BaiduMapVO baiduMapVO, ListSysArea areaList) { SysArea area new SysArea(); String areaId baiduMapVO.getCode(); area.setAreaId(areaId); area.setAreaName(baiduMapVO.getName()); area.setLevel(convertLevel(baiduMapVO.getLevel())); area.setParentId(parentId); areaList.add(area); ListBaiduMapVO districts baiduMapVO.getDistricts(); if (districts ! null !districts.isEmpty()) { for (BaiduMapVO mapVO : districts) { processArea(areaId, mapVO, areaList); } } } private static Integer convertLevel(String level) { if (level null) return null; // 如果已经是数字字符串直接转换 try { return Integer.parseInt(level); } catch (NumberFormatException e) { // 如果不是数字再按字符串映射 switch (level) { case country: return 0; case province: return 1; case city: return 2; case district: return 3; default: log.warn(未知的层级: {}, 默认设为4, level); return 4; } } } }3.调用关系图执行流程说明启动阶段运行AreaSyncUtil.main()启动Spring容器数据获取调用BaiduMapUtil.requestGetSN()获取百度API数据数据转换API返回BaiduMapVO树形结构processArea()递归遍历转换为SysArea扁平结构数据持久化先清空原有数据areaMapper.delete(null)逐条插入新数据areaMapper.insert(area)结束退出关闭Spring容器退出程序sql文件在顶部

相关新闻

Java SpringBoot+Vue3+MyBatis 考研互助交流平台系统源码|前后端分离+MySQL数据库

Java SpringBoot+Vue3+MyBatis 考研互助交流平台系统源码|前后端分离+MySQL数据库

摘要 随着高等教育普及和考研竞争日益激烈,考生对高效、便捷的考研互助交流平台需求显著增加。传统论坛和社交平台功能分散,难以满足考生对精准信息获取、经验分享及学习资源整合的需求。考研互助交流平台旨在提供一个专注于考研群体的垂直社区&#xff…

2026/5/17 8:15:31 阅读更多 →
基于Java+SSM+Flask在线教育系统(源码+LW+调试文档+讲解等)/在线学习平台/网络教育系统/远程教育系统/在线教育软件/在线教育平台/在线课程系统/在线教学系统/在线教育解决方案

基于Java+SSM+Flask在线教育系统(源码+LW+调试文档+讲解等)/在线学习平台/网络教育系统/远程教育系统/在线教育软件/在线教育平台/在线课程系统/在线教学系统/在线教育解决方案

博主介绍 💗博主介绍:✌全栈领域优质创作者,专注于Java、小程序、Python技术领域和计算机毕业项目实战✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 2025-2026年最新1000个热门Java毕业设计选题…

2026/5/17 5:39:46 阅读更多 →
MySQL 主从同步异常使用mysqldump修复

MySQL 主从同步异常使用mysqldump修复

MySQL 主从同步异常使用mysqldump修复 场景描述: MySQL一主一从架构,使用GTID模式同步,无意中测试发现恢复过程中会丢失数据。 如下模拟整个恢复过程。 测试1 丢失数据 模拟从库宕机同步失败mysqldump备份之前主库数据主库备份: […

2026/7/4 15:26:39 阅读更多 →

最新新闻

CTF必学:AES-ECB模式漏洞利用与密文块结构还原实战

CTF必学:AES-ECB模式漏洞利用与密文块结构还原实战

1. 项目概述:为什么AES-ECB是CTF中的“经典考点”?如果你玩过一段时间的CTF,尤其是密码学或Web安全方向的题目,那么“AES-ECB”这个组合词对你来说绝对不陌生。它就像一个老朋友,时不时就会在各种赛题里露个脸&#xf…

2026/7/6 18:58:38 阅读更多 →
Notepad--:跨平台文本编辑器的终极指南,解决你的编码烦恼!

Notepad--:跨平台文本编辑器的终极指南,解决你的编码烦恼!

Notepad--:跨平台文本编辑器的终极指南,解决你的编码烦恼! 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器,目标是做中国人自己的编辑器,来自中国。 项目地址: https://gitcode.com/GitHub_Trend…

2026/7/6 18:54:32 阅读更多 →
jstack 命令实战:5分钟定位 Java 进程 CPU 100% 的元凶线程

jstack 命令实战:5分钟定位 Java 进程 CPU 100% 的元凶线程

jstack 命令实战:5分钟定位 Java 进程 CPU 100% 的元凶线程当 Java 应用在生产环境突然出现 CPU 飙升至 100% 时,整个系统响应速度会急剧下降,直接影响用户体验和业务连续性。作为开发或运维人员,我们需要快速定位问题根源&#x…

2026/7/6 18:54:32 阅读更多 →
R3F-Perf与调试工具集成:Chrome DevTools、React DevTools协同工作流终极指南

R3F-Perf与调试工具集成:Chrome DevTools、React DevTools协同工作流终极指南

R3F-Perf与调试工具集成:Chrome DevTools、React DevTools协同工作流终极指南 【免费下载链接】r3f-perf Easily monitor your ThreeJS performances. 项目地址: https://gitcode.com/gh_mirrors/r3/r3f-perf 在Three.js和React Three Fiber(R3F&…

2026/7/6 18:54:32 阅读更多 →
157、LangChain 生产落地反思:过度抽象的代价、替代方案与最小化依赖

157、LangChain 生产落地反思:过度抽象的代价、替代方案与最小化依赖

157、LangChain 生产落地反思:过度抽象的代价、替代方案与最小化依赖 一个让我凌晨三点还在查日志的Bug 上个月,我接手了一个用LangChain搭建的客服对话系统。代码写得挺“漂亮”——Chain、Agent、Tool、Memory,该有的抽象层一个不少。但上线第三天,用户反馈说机器人突然…

2026/7/6 18:52:31 阅读更多 →
NiGui高级技巧:多线程、定时器与文件对话框的实战应用

NiGui高级技巧:多线程、定时器与文件对话框的实战应用

NiGui高级技巧:多线程、定时器与文件对话框的实战应用 【免费下载链接】NiGui Cross-platform desktop GUI toolkit written in Nim 项目地址: https://gitcode.com/gh_mirrors/ni/NiGui 想要构建功能丰富的跨平台桌面GUI应用吗?NiGui作为一款基于…

2026/7/6 18:52:31 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻