Java通过百度地图API获取定位-普通IP定位

项目中有一个登录邮箱提醒的功能,需要根据IP地址获取定位信息,从而更好地提示用户账号登录的所在地。为此,花费了一些时间来实现这个功能。

在CSDN搜索了一下,发现关于获取定位的文章说明都不够详细,于是决定自己创作一篇文章,希望能够帮助到有需求的小伙伴~

因为博主日常生活中用的导航APP就是百度地图,所以使用百度地图的API来实现这个功能。

目录

百度地图开放平台

开始前的准备工作

学习官网API文档

修改API的AK配置

Java代码获取定位

通过官网生成代码

运行生成的代码

创建接口返回对象

Point.java

Location.java

Content.java

AddressDetail.java

将JSON字符串转成Location对象

代码的最后优化


百度地图开放平台

本篇文章都是围绕百度地图的开放平台官网的相关说明来展开的,访问下面的链接

百度地图开放平台 | 百度地图API SDK | 地图开发icon-default.png?t=N7T8https://lbsyun.baidu.com/index.php?title=%E9%A6%96%E9%A1%B5这是开放平台的首页截图

开始前的准备工作

点击上方导航菜单的开发文档-Web服务API总览

 紧接着,点击左侧菜单中的定位,点击普通IP定位

然后根据开发文档的提示完成步骤1、2、3


 

学习官网API文档

最后点击步骤4,开始使用百度地图的API

如上图,文档已经给出了API的接口地址和参数说明,以及API接口返回的参数格式。

{"address": "CN|北京市|北京市|None|None|100|91","content": {"address": "北京市","address_detail": {"adcode": "110000","city": "北京市","city_code": 131,"district": "","province": "北京市","street": "","street_number": ""},"point": {"x": "116.41338370","y": "39.91092455"}},"status": 0
}

修改API的AK配置

在这里,需要修改一下创建的应用的相关设置。

点击上图的设置按钮来到这个页面,然后拉到页面的底部,修改应用的请求校验方式为sn校验方式,然后点击提交按钮。

把AK复制到示例代码的输入框中,点击确认按钮自动生成获取定位的Java代码,可以说非常方便。

Java代码获取定位

通过官网生成代码

新建一个类SearchHttpAK,把示例代码复制到SearchHttpAK类里,复制按钮在下图红框内。

调整之后的代码如下(真实的AK和SK都已经被博主替换了,这里的5个x改成自己的AK和SK就行了)。

package cn.edu.sgu.www.authority.util;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;/*** 选择AK使用SN校验:* @author heyunlin* @version 1.0*/
public class SearchHttpSN {public static String AK = "xxxxx";public static String SK = "xxxxx";public static String URL = "https://api.map.baidu.com/location/ip?";public static void main(String[] args) throws Exception {SearchHttpSN snCal = new SearchHttpSN();Map<String, String> params = new LinkedHashMap<>(4);params.put("ip", "111.206.214.37");params.put("coor", "bd09ll");params.put("ak", AK);params.put("sn", snCal.caculateSn());snCal.requestGetSN(URL, params);}/*** 选择了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;}StringBuilder queryString = new StringBuilder();queryString.append(strUrl);for (Map.Entry<?, ?> pair : param.entrySet()) {queryString.append(pair.getKey()).append("=");// 第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可// queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8")).append("&");}if (queryString.length() > 0) {queryString.deleteCharAt(queryString.length() - 1);}java.net.URL url = new URL(queryString.toString());System.out.println(queryString.toString());URLConnection httpConnection = (HttpURLConnection) url.openConnection();httpConnection.connect();InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());BufferedReader reader = new BufferedReader(isr);StringBuilder buffer = new StringBuilder();String line;while ((line = reader.readLine()) != null) {buffer.append(line);}reader.close();isr.close();System.out.println("SN: " + buffer);}public String caculateSn() throws UnsupportedEncodingException,NoSuchAlgorithmException {SearchHttpSN snCal = new SearchHttpSN();// 计算sn跟参数对出现顺序有关,get请求请使用LinkedHashMap保存<key,value>,该方法根据key的插入顺序排序;post请使用TreeMap保存<key,value>,该方法会自动将key按照字母a-z顺序排序。// 所以get请求可自定义参数顺序(sn参数必须在最后)发送请求,但是post请求必须按照字母a-z顺序填充body(sn参数必须在最后)。// 以get请求为例:http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak,paramsMap中先放入address,再放output,然后放ak,放入顺序必须跟get请求中对应参数的出现顺序保持一致。Map<String, String> paramsMap = new LinkedHashMap<>(3);paramsMap.put("ip", "111.206.214.37");paramsMap.put("coor", "bd09ll");paramsMap.put("ak", AK);// 调用下面的toQueryString方法,对LinkedHashMap内所有value作utf8编码,拼接返回结果address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakString paramsStr = snCal.toQueryString(paramsMap);// 对paramsStr前面拼接上/geocoder/v2/?,后面直接拼接yoursk得到/geocoder/v2/?address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakyourskString wholeStr = new String("/location/ip?" + 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) {StringBuilder queryString = new StringBuilder();for (Map.Entry<?, ?> pair : data.entrySet()) {queryString.append(pair.getKey()).append("=");// 第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可// queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8")).append("&");}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());StringBuilder sb = new StringBuilder();for (byte b : array) {sb.append(Integer.toHexString((b & 0xFF) | 0x100), 1, 3);}return sb.toString();} catch (java.security.NoSuchAlgorithmException ignored) { }return null;}
}

注意,不要修改这里的map的放入顺序,否则请求接口会报错~

Map<String, String> params = new LinkedHashMap<>(4);params.put("ip", "111.206.214.37");
params.put("coor", "bd09ll");
params.put("ak", AK);params.put("sn", snCal.caculateSn());

运行生成的代码

然后运行一下代码,如果能看到下面这样的运行结果,恭喜你,你已经成功了一大半~

不要纠结获取到的位置信息里很多16进制,因为马上就要把他转成一个自定义的实体类

创建接口返回对象

根据这个API返回的JSON格式字符串的结构,创建4个对应的实体类

Point.java
import lombok.Data;/*** @author heyunlin* @version 1.0*/
@Data
public class Point {private String x;private String y;
}

Location.java
import lombok.Data;/*** @author heyunlin* @version 1.0*/
@Data
public class Location {private Integer status;private String address;private Content content;
}

Content.java
import lombok.Data;/*** @author heyunlin* @version 1.0*/
@Data
public class Content {private Point point;private String address;private AddressDetail address_detail;
}

AddressDetail.java
import lombok.Data;/*** @author heyunlin* @version 1.0*/
@Data
public class AddressDetail {private String adcode;private String city;private String city_code;private String province;private String district;private String street;private String street_number;
}

将JSON字符串转成Location对象

修改一下部分方法的名称,然后把字符串通过fastjson的API转成Location对象

package cn.edu.sgu.www.authority.util;import cn.edu.sgu.www.authority.location.Location;
import com.alibaba.fastjson.JSON;
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.util.LinkedHashMap;
import java.util.Map;/*** 选择AK使用SN校验:* @author heyunlin* @version 1.0*/
public class SearchHttpSN {public static String AK = "xxxxx";public static String SK = "xxxxx";public static String URL = "https://api.map.baidu.com/location/ip?";public static void main(String[] args) throws Exception {String ip = "111.206.214.37";String location = getLocation(ip);System.out.println(JSON.parseObject(location, Location.class));}public static String getLocation(String ip) throws Exception {Map<String, String> params = new LinkedHashMap<>(4);params.put("ip", ip);params.put("coor", "bd09ll");params.put("ak", AK);params.put("sn", caculateSn());return getLocation(URL, params);}/*** 选择了ak,使用SN校验:* 根据您选择的AK已为您生成调用代码* 检测您当前的AK设置了sn检验,本示例中已为您生成sn计算代码* @param strUrl* @param param* @throws Exception*/public static String getLocation(String strUrl, Map<String, String> param) throws Exception {if (strUrl == null || strUrl.length() <= 0 || param == null || param.size() <= 0) {return null;}StringBuilder queryString = new StringBuilder();queryString.append(strUrl);for (Map.Entry<?, ?> pair : param.entrySet()) {queryString.append(pair.getKey()).append("=");// 第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可// queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8")).append("&");}if (queryString.length() > 0) {queryString.deleteCharAt(queryString.length() - 1);}java.net.URL url = new URL(queryString.toString());System.out.println(queryString);URLConnection httpConnection = url.openConnection();httpConnection.connect();InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());BufferedReader reader = new BufferedReader(isr);StringBuilder sb = new StringBuilder();String line;while ((line = reader.readLine()) != null) {sb.append(line);}reader.close();isr.close();return sb.toString();}public static String caculateSn() throws UnsupportedEncodingException {// 计算sn跟参数对出现顺序有关,get请求请使用LinkedHashMap保存<key,value>,该方法根据key的插入顺序排序;post请使用TreeMap保存<key,value>,该方法会自动将key按照字母a-z顺序排序。// 所以get请求可自定义参数顺序(sn参数必须在最后)发送请求,但是post请求必须按照字母a-z顺序填充body(sn参数必须在最后)。// 以get请求为例:http://api.map.baidu.com/geocoder/v2/?address=百度大厦&output=json&ak=yourak,paramsMap中先放入address,再放output,然后放ak,放入顺序必须跟get请求中对应参数的出现顺序保持一致。Map<String, String> paramsMap = new LinkedHashMap<>(3);paramsMap.put("ip", "111.206.214.37");paramsMap.put("coor", "bd09ll");paramsMap.put("ak", AK);// 调用下面的toQueryString方法,对LinkedHashMap内所有value作utf8编码,拼接返回结果address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakString paramsStr = toQueryString(paramsMap);// 对paramsStr前面拼接上/geocoder/v2/?,后面直接拼接yoursk得到/geocoder/v2/?address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakyourskString wholeStr = new String("/location/ip?" + paramsStr + SK);System.out.println(wholeStr);// 对上面wholeStr再作utf8编码String tempStr = URLEncoder.encode(wholeStr, "UTF-8");// 调用下面的MD5方法得到最后的sn签名return MD5(tempStr);}// 对Map内所有value作utf8编码,拼接返回结果public static String toQueryString(Map<?, ?> data) {StringBuilder queryString = new StringBuilder();for (Map.Entry<?, ?> pair : data.entrySet()) {queryString.append(pair.getKey()).append("=");// 第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可// queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8")).append("&");}if (queryString.length() > 0) {queryString.deleteCharAt(queryString.length() - 1);}return queryString.toString();}// 来自stackoverflow的MD5计算方法,调用了MessageDigest库函数,并把byte数组结果转换成16进制public static String MD5(String md5) {try {java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");byte[] array = md.digest(md5.getBytes());StringBuilder sb = new StringBuilder();for (byte b : array) {sb.append(Integer.toHexString((b & 0xFF) | 0x100), 1, 3);}return sb.toString();} catch (java.security.NoSuchAlgorithmException ignored) { }return null;}}

运行代码,效果如下:

在使用的时候,只需要传入IP地址即可获取到定位信息~

代码的最后优化

上面的代码已经是进行了一定的优化,除此之外,可以把AK和SK配置到application.yml中,可以动态地修改。最后重命名一下这个类,改成类似LocationUtils这样的名字。

好了,文章就分享到这里了,看完如果觉得对你有所帮助,不要忘了点赞+收藏哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/835046.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么要学Python?学Python有什么用?

为什么要学Python&#xff1f;学Python有什么用&#xff1f; 在当今的数字化时代&#xff0c;编程已成为一项宝贵的技能。Python&#xff0c;作为一种流行的编程语言&#xff0c;因其易于学习和强大的功能而受到全球开发者的青睐。本文将探讨学习Python的原因和它的实际应用&am…

【操作系统期末速成】​操作系统概述(定义|功能|特征)|发展阶段和分类|结构设计|概念补充

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;操作系统&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到…

Nginx部署前后端分离项目

部署前后端分离项目&#xff0c;要求前端项目、后端项目、数据库分别部署在3台服务器 服务器准备 服务器名IP软件包前端192.168.99.137nginx后端192.168.99.139jar数据库192.168.99.100mariadb 1、前端服务器 yum install -y epel-release && yum install -y nginx…

官宣:vAsterNOS正式发布!开放网络操作系统免费试用!

近期&#xff0c;vAsterNOS&#xff08;设备模拟器&#xff09;正式发布&#xff0c;可以满足用户快速了解 AsterNOS、体验实际操作、搭建模拟网络的需求&#xff0c;可运行在GNS3、EVE-NG等网络虚拟软件中。 AsterNOS 网络操作系统是星融元为人工智能、机器学习、高性能计算、…

vCenter 7.3证书过期无法登录处理方法

登录报错&#xff1a;如下图 Exception in invking authentication handler [SSL: CERTIFICATE_VERIFY_FAILED] certificate vertify failed: certificate has expired(_ssl.c:1076) 处理方法1&#xff1a;推荐&#xff0c;可行 登录vCenter控制台&#xff0c;AltF3切换至命令…

antdVue 自定义table列配置

最近做项目的时候需要对页面的table进行列配置的需求 子组件 <div><a-modaltitle"列配置" :visible"visible" :closable"false" :footer"null"width"800px" height"448px"><div><a-row>…

在linux里登录远程服务器

在linux里登录远程服务器。在虚拟终端里输入命令&#xff1a; ssh 远程服务器ip -l username 然后输入登录密码&#xff0c;就可以登录到远程服务器的命令行界面。登录方便&#xff0c;字体也可以在本地机的虚拟终端里设置得大一点。 下面是一张截屏图片。

系统Cpu利用率降低改造之路

系统Cpu利用率降低改造之路 一.背景 1.1 系统背景 该系统是一个专门爬取第三方数据的高并发系统&#xff0c;该系统单台机器以每分钟400万的频次查询第三方数据&#xff0c;并回推给内部第三方系统。从应用类型上看属于IO密集型应用,为了提高系统的吞吐量和并发&#xff0c;…

音频数字信号I2S一些知识理解

(1)I2S单向基本传输需要几根线传输音频信号? 3根线 LRCK SCLK(也叫BLK) DATA(单向) (2)如何理解I2S MASTER或者SLAVE的模式&#xff1f; codec的i2s作为slave mode,LRCK和SCLK来自于soc主控端,codec端自动检测MCLK和LRCK codec的i2s作为master mode,codec通过MCLK LRCLKDIV…

CSS-浮动

float (浮动) 作用&#xff1a;盒子的顶点是一样的&#xff0c;具备行内块的特征&#xff0c;能设置宽高 属性&#xff1a;float 属性值&#xff1a;left 浮动在网页左边 right 浮动在网页右边 .a{width: 100px;height: 100px;float:left;background-color: red;}.b…

drawio 网页版二次开发(1):源码下载和环境搭建

目录 一 说明 二 源码地址以及下载 三 开发环境搭建 1. 前端工程地址 2. 配置开发环境 &#xff08;1&#xff09;安装 node.js &#xff08;2&#xff09;安装 serve 服务器 3. 运行 四 最后 一 说明 应公司项目要求&#xff0c;需要对drawio进行二次开发&…

VUE 或 Js封装通用闭包循环滚动函数

1、vue3 闭包滚动函数的使用 js 调用也基本雷同 // 滚动Tab组件const scoreTabRef ref()// 滚动的选项const scrollOption ref({// 滚动的Dom元素scrollDom: null,// 滚动的时间间隔scrollInterval: 1500,// 滚动的距离scrollSep: 100,// 滚动历时时间scrollDuration: 10…

Microsoft Project使用简明教程

一.认识Microsoft Project Microsoft Project 是微软公司开发的项目管理软件&#xff0c;用于规划、协调和跟踪项目的进度、资源和预算&#xff0c;如下图所示&#xff0c;左边是任务的显示&#xff0c;右边是一个日程的显示图&#xff0c;最上方的长方形处在我们项目设定日程…

Python 3 中zip()函数的用法

1 创作灵感 我们在阅读代码的时候&#xff0c;经常会看到zip函数&#xff0c;有的时候还和循环在一起用&#xff0c;今天举几个例子测试一下该函数的用法 2.应用举例 &#xff08;1&#xff09;定义了两个列表一个是num,一个是letter (2)使用zip可以把num列表和letter列表中…

【高阶数据结构】图 -- 详解

一、图的基本概念 图 是由顶点集合及顶点间的关系组成的一种数据结构&#xff1a;G (V&#xff0c; E)。其中&#xff1a; 顶点集合 V {x | x属于某个数据对象集} 是有穷非空集合&#xff1b; E {(x,y) | x,y属于V} 或者 E {<x, y> | x,y属于V && Path(x, y…

pdf编辑软件,四款软件让你轻松玩转PDF编辑!

在信息爆炸的当今时代&#xff0c;PDF格式文档因其跨平台、不易被篡改的特性而深受大家喜爱。然而&#xff0c;如何高效地编辑PDF文档却成为许多人的难题。今天&#xff0c;我将为大家推荐四款实用的PDF编辑软件&#xff0c;让你轻松玩转PDF编辑&#xff0c;告别繁琐操作&#…

Springboot集成Mybatispuls操作mysql数据库-04

MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强而不做改变。它支持所有MyBatis原生的特性&#xff0c;因此引入MyBatis-Plus不会对现有的MyBatis构架产生任何影响。MyBatis-Plus旨在简化开发、提高效率&#xff0c;…

【机器学习与实现】线性回归分析

目录 一、相关和回归的概念&#xff08;一&#xff09;变量间的关系&#xff08;二&#xff09;Pearson&#xff08;皮尔逊&#xff09;相关系数 二、线性回归的概念和方程&#xff08;一&#xff09;回归分析概述&#xff08;二&#xff09;线性回归方程 三、线性回归模型的损…

3D Gaussian Splatting for Real-Time Radiance Field Rendering 论文阅读

如此热门的项目&#xff0c;网络上有很多大牛分析了这篇文章的做法&#xff0c;在这里简单记录一下个人粗浅的理解。 关于各种数学表达式的推导&#xff0c;论文和参考资料中都提供了较为详细的解读&#xff0c;本人能力有限&#xff0c;这一部分理解不够深刻&#xff0c;先不做…

【CSDN搜材料的小技巧】怎么快速查到高质量最新的内容

问题描述: 我最近搜CSDN已经搜累了&#xff0c;好多东西明显是有问题的&#xff0c;还有一堆人复制粘贴&#xff0c;从海量文章中提取出最新且高质量文章成了当务之急&#xff01; 解决方案: 我本来想写个爬虫按照文章的收藏或者点赞排序的&#xff0c;无意中看到了这篇文章…