跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Java 实现百度地图 SN 权限签名及搜索接口调用

百度地图 SN 权限签名用于验证应用访问请求合法性,防止未授权访问。介绍在 Java 中生成 SN 签名的原理与步骤,包括参数排序、编码处理及 MD5 加密过程。通过地点搜索接口示例,展示如何构建请求 Map、拼接字符串并计算签名。同时分析校验失败常见原因,如字符编码错误、参数顺序不一致及 timestamp 设置问题,帮助开发者解决集成中的技术难点。

Kubernet发布于 2026/3/22更新于 2026/6/1023 浏览
Java 实现百度地图 SN 权限签名及搜索接口调用

前言

百度地图作为地图服务提供商,为开发者提供了丰富多样的 API 接口。然而,在使用百度地图 API 时,SN 权限签名这一环节常常成为开发过程中的技术难点,也是确保应用安全稳定使用百度地图服务的关键所在。本文将深入探讨 Java 开发者如何高效、准确地搞定百度地图 SN 权限签名实践。

一、SN 签名简介

1、SN 签名是什么

SN 权限签名是一种安全机制,用于验证应用对百度地图 API 的访问请求是否合法。通过为每个请求生成唯一的签名,百度地图能够有效防止未经授权的访问和滥用。在之前的接口调用中,我们仅在开放平台中申请了应用,并且分配了 AK,而接口的调用也是通过 AK 来完成的。简要过程如下所示:

开发者首先需要在百度地图开放平台创建应用,然后获取应用访问 key 即 AK。然后就可以进行应用开发,比如地点检索、路径导航、天气服务等,在调用这些服务时必须要携带 AK 在每次服务调用时进行访问请求。

以地点检索服务为例,在官方的开发者文档中对于 SN 的描述如下:

| sn | 开发者的权限签名。sn 校验说明 | string(50) | 可选,若开发者所用 AK 的校验方式为 SN 校验时该参数必须。 | | timestamp | 设置 sn 后该值必填。 | string(50) | 设置 sn 后该值必填。 |

2、如何开启 SN 签名

sn 作为保护开发者的一种重要手段,如何在创建应用时开启 SN 签名呢?这里将重点讲解。首先我们登录百度地图开发者平台,进入到控制台程序中。

在这里界面可以看到自己创建的应用列表,为了不影响之前的应用,我们创建一个新的应用。点击红色框中的'创建应用'按钮来创建新的应用。说明,如果我们选择修改原来的应用的严重模式,那么会影响之前的验证模式,因此大家一定要谨慎选择,根据自己的实际情况来进行设置,如果只是测试的话,没有关系,随时切换,创建一个应用即可。点击创建应用后,弹出以下界面:

按照要求填写好应用名称、应用类型(请注意:'服务端 AK'不再支持浏览器端使用;在浏览器端使用,请选择'浏览器端 AK',例如 JavaScript API 只支持浏览器类型 AK。对于以前申请的服务端 AK,不变更即不受影响,仍支持浏览器端使用;如更新老的服务端 AK,再次保存,则按新创建 AK 处理,不再支持浏览器端使用。)、启用服务、请求校验方式(默认是使用 IP 限制,这里我们选择 SN 校验),信息输入完成后点击提交即可。

请记住这里的 SK,在后面的签名中还会使用到的。到此,就创建好了一个支持 SN 签名的应用,后面就会使用这个应用来访问相关接口。

3、SN 签名算法

计算 sn 跟参数对出现顺序有关,get 请求请使用 LinkedHashMap 保存<key,value>,该方法根据 key 的插入顺序排序;post 请使用 TreeMap 保存<key,value>,该方法会自动将 key 按照字母 a-z 顺序排序。这里有一个至关重要的知识点,即请求的参数,在实际的地图接口中,我们传入的顺序是一定的,怎么样保证这个签名的有效性呢?开发者会根据自己的应用 SK 和 AK,加上请求参数生成一个 SN,然后将请求发送到服务端,如果两者匹配,请求返回,反之会报 APP SN,SERVER 类型 APP 有两种校验方式 IP 校验和 SN 校验,当用户请求的 SN 和服务端计算出来的 SN 不相等的时候提示 SN 校验失败。这里以检索接口为例,简单讲一下 SN 的签名算法,请求的接口是 V2 版本的检索接口,地址如下:

https://api.map.baidu.com/place/v2/search?

请求的参数如下:

String query = "36"; String region = "158";// 158 表示长沙市 String scope = "2"; String output = "json"; String ret_coordtype = "WGS84"; int page_size = 20; int page_num = 0;

其生成算法如下图:

在下一节 Java 中应用详细进行代码调用实例。

二、在 Java 中的应用

本节将以地点搜索为例,重点讲解如何在 Java 中使用 SN 签名的生成及具体调用,通过实例展示,让大家掌握实际的项目开发过程。

1、请求 Map 参数化

这里以地点搜索接口为例,首先定义一个数据请求参数 Map,代码如下:

Map<String, String> params = new LinkedHashMap<String, String>(); // 美食餐饮 -- 543c03f1792d66df98709b45b009d67b String query = "邮政"; String region = "158";// 158 表示长沙市 String scope = "2"; String output = "json"; String ret_coordtype = "WGS84"; int pageSize = 20; int pageNum = 0; params.put("query", query); params.put("region", region); params.put("output", output); params.put("scope", scope); params.put("ret_coordtype", ret_coordtype); params.put("page_size", String.valueOf(pageSize)); params.put("page_num", String.valueOf(pageNum)); params.put("ak", AK);

这个 Map 是生成 SN 签名的基础,在后续的认证过程中会持续用到。

2、SN 签名生成

对于 Java 开发者来说,掌握正确的 SN 权限签名方法,不仅可以确保应用能够稳定地调用百度地图服务,还能避免因签名错误导致的频繁接口调用失败,从而提升开发效率和用户体验。为了在接口请求中对中文的字符进行转义,因此要求我们首先进行统一编码,将 map 拼接成请求字符串,核心方法如下:

// 对 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(); }

然后拼接请求接口前缀和带上 SK 值,sk 值就是在前面创建应用时获取到的信息。拼接方法较简单,代码如下:

// 对 paramsStr 前面拼接上/geocoder/v2/?,后面直接拼接 yoursk 得到/geocoder/v2/?address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakyoursk String wholeStr = new String("/place/v2/search?" + paramsStr + SK); System.out.println(wholeStr); // 对上面 wholeStr 再作 utf8 编码 String tempStr = URLEncoder.encode(wholeStr, "UTF-8");

最后对调用 MD5 加密生成 SN 值,调用及生成核心方法如下:

// 调用下面的 MD5 方法得到最后的 sn 签名 String sn = snCal.MD5(tempStr); System.out.println("sn===>" + sn); 

生成 MD5 的方法很多,这里分享一种比较简单方法,如下:

// 来自 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 (java.security.NoSuchAlgorithmException e) { } return null; }

3、搜索接口调用

为了演示实际的搜索方法,这里创建最原生的 Java 请求对象来进行发送网络请求,使用原生的方式创建请求对象及发送请求的核心代码如下:

/** * 选择了 ak,使用 SN 校验:根据您选择的 AK 已为您生成调用代码 检测您当前的 AK 设置了 sn 检验,本示例中已为您生成 sn 计算代码 *
* @param strUrl
* @param param
* @throws Exception */ public void requestGetSN(String strUrl, Map<String, String> param) throws Exception { if (strUrl == null || strUrl.length() <= 0 || param == null || param.size() <= 0) { return; } 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); } java.net.URL url = new URL(queryString.toString()); URLConnection httpConnection = (HttpURLConnection) 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(); System.out.println("SN: " + buffer.toString()); }

在 Main 方法中调用 SN 签名生成以及实际调用的代码如下,首先需要替换您的应用 ak 和 sk 的值,方可运行。

package com.yelang.project.unihttp; import org.springframework.web.util.UriUtils; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.security.NoSuchAlgorithmException; import java.util.LinkedHashMap; import java.util.Map; public class SearchHttpSN { public static String AK = "yourak"; public static String SK = "yoursk"; public static String URL = "https://api.map.baidu.com/place/v2/search?"; public static void main(String[] args) throws Exception { SearchHttpSN snCal = new SearchHttpSN(); Map<String, String> params = new LinkedHashMap<String, String>(); String query = "邮政"; String region = "158";// 158 表示长沙市 String scope = "2"; String output = "json"; String ret_coordtype = "WGS84"; int pageSize = 20; int pageNum = 0; params.put("query", query); params.put("region", region); params.put("output", output); params.put("scope", scope); params.put("ret_coordtype", ret_coordtype); params.put("page_size", String.valueOf(pageSize)); params.put("page_num", String.valueOf(pageNum)); params.put("ak", AK); params.put("sn", snCal.caculateSn()); snCal.requestGetSN(URL, params); } }

执行完成后,在控制台看到以下输出表示成功发起了请求,并且返回了数据,表示通过了 SN 验证并且返回了指定数据:

三、APP SN 校验失败可能的原因

在实际开发过程中,Java 开发者在进行百度地图 SN 权限签名时往往会面临诸多挑战。一方面,签名算法本身涉及多个参数的处理和特定的加密规则,稍有不慎就可能导致签名错误;另一方面,不同类型的百度地图 API 接口可能对签名参数的要求存在差异,这进一步增加了开发的复杂性。此外,随着百度地图服务的不断更新和升级,签名相关的规则和要求也可能发生变化,这就要求开发者必须及时跟进和掌握最新的签名规范,以确保应用的持续稳定运行。出现问题的原因可能有以下两个问题,即字符编码问题和参数顺序问题。

1、字符编码问题

API 请求中需要用到中文或一些特殊字符的参数,如 query、region 等,为了避免提交到后台乱码,需要对这几个参数值进行编码处理,转换成 UTF-8 字符的二字符十六进制值,凡是不在下表中的字符都需要进行编码。

字符集合字符
URL 非保留字a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 - _ . ~
URL 保留字! * ' ( ) ; : @ & = + $ , / ? % # [ ]

如果中文参数中使用 URL 保留字字符的字面意思,例如:region 关键字取值为"?北京",检索关键字包含一个问号,此问号也必须进行编码。在上面的内容,我们使用 UTF-8 进行转义,因此很好的避免了由于字符编码问题引起的问题。

2、参数顺序

另一个容易出现的问题就是参数的顺序问题,比如我们随意调整请求参数的顺序,计算出来的 SN 值为:sn==>0d5e1ea029c398ed47ef8cb8a0847eaf,未替换之前的 SN 值为:ba424c6d1f2661e30bcc88a364ee8c6e,此时就会出现:SN: {"status":211,"message":"APP SN 校验失败"}。所以如果碰到 SN 签名不通过的问题,首先应该查看参数的顺序,因为 SN 的签名算法很简单,就是按顺序计算 MD5,因此顺序的改变一定会导致 MD5 值的变化,从而导致服务端加密时不匹配,从而导致请求失败。

3、timestamp 的设置

官方文档中,timestamp 字段在设置了 sn 签名时要求必填,但是在实测过程中,并没有传递该参数,也不影响实际的请求,可能这是官方隐藏的彩蛋吧。

四、总结

以上就是本文的主要内容,本文将深入探讨 Java 开发者如何高效、准确地搞定百度地图 SN 权限签名实践,旨在为广大 Java 开发者提供一份清晰、实用的指南,帮助大家顺利跨越这一技术门槛,更好地利用百度地图的强大功能为自己的应用赋能。通过本文的深入讲解和实践指导,期望每一位 Java 开发者都能对百度地图 SN 权限签名有清晰、准确的认识和掌握,并能够将其熟练应用于实际开发项目中。无论你是初入职场的 Java 开发新手,还是经验丰富的资深开发者,本文都将为你提供有价值的参考和借鉴,帮助你在百度地图应用开发的道路上更加顺畅地前行。

目录

  1. 前言
  2. 一、SN 签名简介
  3. 1、SN 签名是什么
  4. 2、如何开启 SN 签名
  5. 3、SN 签名算法
  6. 二、在 Java 中的应用
  7. 1、请求 Map 参数化
  8. 2、SN 签名生成
  9. 3、搜索接口调用
  10. 三、APP SN 校验失败可能的原因
  11. 1、字符编码问题
  12. 2、参数顺序
  13. 3、timestamp 的设置
  14. 四、总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Ubuntu 部署 OpenClaw 并接入飞书机器人
  • IoTDB AINode 实战:SQL 原生时序 AI 建模与预测
  • 使用本地大模型 Llama3 进行数据分类标记
  • Fooocus 部署实战:本地配置与云方案对比
  • Moon VR Video Player 中文版:支持 8K/12K 多音轨及外挂字幕
  • 【火】Spatial Joy 2025 全球 AR&AI 赛事:开发者要的资源、玩法、避坑攻略都在这
  • GitHub Copilot Pro 使用指南与模型配额解析
  • 初识 AI 语言大模型基础概念
  • OpenClaw 安装部署全流程 - 搭建自托管 AI 助手
  • Ubuntu 20.04 虚拟机安装与配置实战指南
  • 基于 BERT+Seq2Seq 架构的智能对话系统构建指南
  • OpenClaw 安装部署全流程:搭建自托管 AI 助手网关
  • Java 响应式编程核心:Mono 接口实战指南
  • Whisper 安装与配置指南:环境搭建与验证
  • Spatial Joy 2025 全球 AR&AI 开发大赛参赛指南与避坑攻略
  • 人工智能背后的数学基础:微积分与线性代数(一)
  • 修复 Anaconda 开始菜单快捷方式丢失及 mkmenus 报错
  • 9款AI写论文工具实验室级测评
  • Spatial Joy 2025 全球 AR&AI 开发大赛参赛指南与资源介绍
  • DeepSeek + 本地知识库搭建指南:基于 Cherry Studio 与 AnythingLLM

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online