解决Java使用Jsoup后台调用天地图地理编码接口的几个问题

目录

前言

一、天地图的地理编码接口

1、相关的API介绍

 2、响应接口

二、使用JSOUP调用相应接口面对的问题及应对

1、第一关访问路径的问题

2、第二关UnsupportedMimeTypeException

3、可能的http获取403问题

三、总结


前言

        如果你现在的项目中有如下的需求,比如已知一个中国境内的地名地址信息,然后需要知道这个地名地址对应的位置信息,比如经纬度信息。要实现上面的需求呢,比如可以通过其它的地图厂商,比如百度地图或者高德地图的开放API接口来实现将文字的地理位置转换为经纬度的位置信息。这是直接调用在线服务的方式,当然我们也可以自己整理基础数据,比如去互联网上搜集别人分享的地名地址信息还有村镇行政区划信息,当有了这些基础的地理数据之后,也可以自己构建私有的地名服务,但是这样需要的信息量是比较大的,也是比较困难的,同时数据的准确性和及时程度都是有一定的延迟的。对基础数据的搜集、清理、存储、检索做成服务化的应用功能。当前在前面的在线服务调用中,可能存在一个服务收费的问题,比如超过了一定的次数就会收费。

        本文分享一种有一定使用次数限制的地理地名地址转换成经纬度的在线服务接口。那就是国家开放的天地图web接口,通过注册成为天地图网站的正式用户,就可以使用它的在线API,虽然面向普通开发者,它也是有一定的次数限制,但是如果我们的量不大,甚至说是一些固定的场景,比如有限的地名地址查找,一天的调用次数是少于3000的,其实是可以满足我们的日常需求的。而且天地图的信息是国家地理中心发布,具有较高的权威性。在之前的一篇Leaflet进行天地图的服务调用的博客中,原文地址:基于天地图使用Leaflet.js进行WebGIS开发实战。博客中讲解的是前端的调用方式,如果我们想将一些地址转换成地理坐标后,还可以保存起来,就需要使用后端服务调用的方式。

        本文即以Java语言为例,我们使用Jsoup作为接口请求工具来访问天地图的地理编码接口。详细讲解在调用天地图的地理编码接口中会遇到的一些艰难险阻,通过解决接口调用过程中的这些问题,掌握如何正确的进行jsoup调用天地图的服务。

一、天地图的地理编码接口

        最开始的时候还是将天地图的地理编码接口给大家介绍一下,让大家有个基本的了解。在天地图的官网上找到地理编码接口,如下图所示:

1、相关的API介绍

        关于天地图的API,我们直接来看官方网站上的介绍,关于请求参数和响应的参数,官网上都定义得比较详细。天地图地理编码API是一类简单的HTTP/HTTPS接口,是指由结构化地址数据(如:北京市海淀区莲花池西路28号)转换为对应坐标点(经纬度)功能,地址解析仅限于国内。 使用地理编码服务前您需要申请Key。

参数值参数说明参数类型是否必备备注(值域)
keyWord请求关键字string

请求: http://api.tianditu.gov.cn/geocoder?ds={"keyWord":"北京市延庆区延庆镇莲花池村前街50夕阳红养老院"}&tk=您的密钥

{"location": {"lon": "116.001688","level": "地名地址","lat": "40.453228"},"status": "0","msg": "ok","searchVersion": "4.8.0"
}

 2、响应接口

        在调用了相应的服务接口后,可以看到如上的相应数据。来看一下官网的响应接口参数。

参数值参数说明参数类型备注(值域)
status返回状态string0:正常返回,101:结果为空,404:出错。
msg返回信息stringOK:正常,其他异常。
location地址信息json地址信息

        其中locaction地址信息的对象如下:

参数值参数说明参数类型备注(值域)
lon坐标点显示经度Double必须返回。
lat坐标点显示纬度Double必须返回。
level类别名称string非必须返回。
typeRound附近相似点Array开启周边查询必需返回。

        上面对将要使用的接口进行介绍,方便大家后面在调用时有所了解。下面将结合java语言来重点讲解如何进行接口的调用。

二、使用JSOUP调用相应接口面对的问题及应对

        在了解了天地图的相关接口后,我们即以java开发语言为例,使用Jsoup来进行天地图的接口调用。详细记录在使用Jsoup进行接口访问时遇到的常见问题,以及如何解决上面的问题,正确的获取我们的响应信息,并转换成我们想要的java对象。

1、第一关访问路径的问题

        首先我们在后台按照官方网站的要求,将代码改写成直接请求的方式,具体的代码如下所示:

/**
* 普通请求测试,请求字符串未转义,会报错java.net.MalformedURLException
*/
@Test
public void testSimpleTdtQuery() {String address = "长郡梅溪湖中学";String queryParams = "ds={'keyWord':'" + address + "'}";String url = TDT_ADDRESS_API + queryParams+"'&tk=" + TDT_SERVER_KEY;System.out.println(url);Document document;try {document = Jsoup.connect(url).get();Elements elements = document.select("body");System.out.println(elements.get(0).html().toString());} catch (IOException e) {e.printStackTrace();}
}

        上述代码表示连接天地图的官方接口,接着我们来运行一下,会发现程序报如下的错误:

        错误代码如下,大致的错误:

https://api.tianditu.gov.cn/geocoder?ds={'keyWord':'长郡梅溪湖中学'}'&tk=473af7dc18cafb6b993616a0ce8e1ead
java.net.MalformedURLException: Illegal character in query at index 40: https://api.tianditu.gov.cn/geocoder?ds={'keyWord':'长郡梅溪湖中学'}'&tk=473af7dc18cafb6b993616a0ce8e1eadat org.jsoup.helper.CookieUtil.asUri(CookieUtil.java:80)at org.jsoup.helper.CookieUtil.applyCookiesToRequest(CookieUtil.java:41)at org.jsoup.helper.HttpConnection$Response.createConnection(HttpConnection.java:1033)at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:856)at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:829)at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:366)at org.jsoup.helper.HttpConnection.get(HttpConnection.java:353)

        可以看到,这里提示的错误信息是访问的URL有问题,在访问地址的40个字符的位置,就是{}这里,通过提示就大概指导了如何解决。我们将这个花括号进行转义即可。解决的办法很简单,只要将访问的参数地址换成以下的地址即可。

String queryParams = "ds=%7B'keyWord':'" + address + "'%7D";

        修改后再执行就不会再报这个url路径的问题了。

2、第二关UnsupportedMimeTypeException

        在顺利通过第一关的接口访问后,本来是期望可以正常访问到数据的,但是一波未平,一波又起,解决了访问路径的问题,又遇到以下的问题。我们提供访问路径修正后的代码:

/**
* 普通请求测试,未设置忽略content_type,会报错org.jsoup.UnsupportedMimeTypeException
*/
@Test
public void testSimpleTdtQueryWithIgnoreContentType() {String address = "长郡梅溪湖中学";String queryParams = "ds=%7B'keyWord':'" + address + "'%7D";String url = TDT_ADDRESS_API + queryParams+"'&tk=" + TDT_SERVER_KEY;System.out.println(url);Document document;try {document = Jsoup.connect(url).get();Elements elements = document.select("body");System.out.println(elements.get(0).html().toString());Gson gson = new Gson();TdtAddressInfo info = gson.fromJson(elements.get(0).html().toString(), TdtAddressInfo.class);System.out.println(info);System.out.println(info.getLocation().getLon());} catch (IOException e) {e.printStackTrace();}
}

        运行后的结果如下所示:

        显示的关键错误信息如下:

https://api.tianditu.gov.cn/geocoder?ds=%7B'keyWord':'长郡梅溪湖中学'%7D'&tk=473af7dc18cafb6b993616a0ce8e1ead
org.jsoup.UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/*+xml. Mimetype=application/json; charset=UTF-8, URL=https://api.tianditu.gov.cn/geocoder?ds=%7B'keyWord':'%E9%95%BF%E9%83%A1%E6%A2%85%E6%BA%AA%E6%B9%96%E4%B8%AD%E5%AD%A6'%7D'&tk=473af7dc18cafb6b993616a0ce8e1eadat org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:900)at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:829)at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:366)at org.jsoup.helper.HttpConnection.get(HttpConnection.java:353)at com.yelang.project.education.TestViolationTrainingCase.testSimpleTdtQueryWithUserAgent(TestViolationTrainingCase.java:119)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)

        从上面的提示信息来看,关键的主体信息是org.jsoup.UnsupportedMimeTypeException:Unhandled content type. Must be text/*, application/xml, or application/*+xml. Mimetype=application/json; charset=UTF-8,可以看到是响应的内容类型不受支持。那么这个问题怎么解决呢?

        其实解决办法很简单,在jsoup中,我们可以设置忽略,设置方法如下:

document = Jsoup.connect(url).ignoreContentType(true).get();

        上面的设置就是忽略contenttype,不做任何转换。直接返回字符信息。将响应结果从后台获取后,我们就可以进行数据转换。将json数据转换为java对象。我们来定义对应的java实体类:

package com.yelang.project.education.domain;
import java.io.Serializable;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class TdtAddressInfo implements Serializable{private static final long serialVersionUID = -1013000744231947989L;private String msg;//OK:正常,其他异常。private String status;//0:正常返回,101:结果为空,404:出错。private String searchVersion;//查询版本private TdtLocation location;//位置信息
}
package com.yelang.project.education.domain;
import java.io.Serializable;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class TdtLocation implements Serializable{private static final long serialVersionUID = 5155681441498287691L;private Double lon;//lon	坐标点显示经度	Double	必须返回。private Double lat;//lat	坐标点显示纬度	Double	必须返回。private String level;//类别名称	string	非必须返回。private String typeRound;//附近相似点	Array	开启周边查询必需返回。private Double score;//打分
}

         经过转换后的程序运行结果如下:

https://api.tianditu.gov.cn/geocoder?ds=%7B'keyWord':'长郡梅溪湖中学'%7D'&tk=473af7dc18cafb6b993616a0ce8e1ead
{"msg":"ok","location":{"score":81,"level":"兴趣点","lon":"112.870830","lat":"28.192800","keyWord":"长郡梅溪湖中学"},"searchVersion":"6.4.9V","status":"0"}
TdtAddressInfo(msg=ok, status=0, searchVersion=6.4.9V, location=TdtLocation(lon=112.87083, lat=28.1928, level=兴趣点, typeRound=null, score=81.0))
112.87083

         经过上述的编码设置即完成地理编码接口的调用,也返回了相应的地理信息。

3、可能的http获取403问题

        在访问的过程中,如果顺利的话,可能你不会遇到请求403报错的问题。类似于下面的这种错误。

org.jsoup.HttpStatusException: HTTP error fetching URL. Status=403, URL=http://www.example.comat org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:537)at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:493)at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:205)at org.jsoup.helper.HttpConnection.get(HttpConnection.java:194)at com.javacodeexamples.libraries.jsoup.Jsoup403ForbiddenExample.main(Jsoup403ForbiddenExample.java:19)

        如果在实际使用过程当中遇到这种问题,您可以采用下面的方法进行应对。即可设置用户的user-agent来进行解决。

document = Jsoup.connect(url).header("User-Agent", DEFAULT_USER_AGENT)//添加user-agent 可以避免403的报错.ignoreContentType(true)//设置忽略可以防止org.jsoup.UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/xhtml+xml.get();
	private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2";

        如果遇到上面的问题,按照上面的解决办法来修复即可。

三、总结

        以上就是本文的主要内容, 本文即以Java语言为例,我们使用Jsoup作为接口请求工具来访问天地图的地理编码接口。详细讲解在调用天地图的地理编码接口中会遇到的一些艰难险阻,通过解决接口调用过程中的这些问题,掌握如何正确的进行jsoup调用天地图的服务。行文仓促,难免有很多不足之处,针对不足还肯定各位专家博主批评指正,不胜感激。

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

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

相关文章

[JavaEE] 工作流- Activiti7 框架详解

目录 1、Activiti介绍 1.1、BPMN设计器 1.2、常见流程符号 1.2.1、事件event 1.2.2、活动activiti 1.2.3、流向flow 2、入门案例 2.1、需求说明 2.2、初始环境 2.2.1、添加依赖 2.2.2、添加配置 2.2.3、添加引导类 2.2.4、启动项目 2.2.5、表结构 2.2.6、常见ap…

解决 mfc140.dll 文件丢失的问题,5种mfc140.dll解决方法

当您尝试启动一个用 Microsoft Visual Studio 2015 开发的 Windows 应用程序时,如果出现“无法找到 mfc140.dll 文件”的错误,请不要紧张。这类问题通常由DLL文件缺失、损坏或未正确安装引起。好消息是,存在多种解决方案可以帮助您解决这一挑…

Vue指令:v-cloak、v-once、v-pre 指令

Vue 指令系列文章: 《Vue插值:双大括号标签、v-text、v-html、v-bind 指令》 《Vue指令:v-cloak、v-once、v-pre 指令》 《Vue条件判断:v-if、v-else、v-else-if、v-show 指令》 《Vue循环遍历:v-for 指令》 《Vue事件…

【机器学习练习】糖尿病预测

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 一、数据预处理 1. 数据导入 import numpy as np import pandas as pd import seaborn as sns from sklearn.model_selec…

css 将背景图片居中显示,并且显示全,不拉伸的效果实现,图片设置宽度,高度自适应,并且显示全。

1、背景自适应的css: .bg-tns {background-image: url(img/xxx.jpg);background-size: cover;background-position: center; /* 将图片居中显示 */min-height: calc(100vh-100px); /* 确保至少为视口高度 */} 这个布局是这样的: 这里的背景图的高度&am…

unity Standard Assests资源商店无法安装解决方案

Unity游戏开发 “好读书,不求甚解;每有会意,便欣然忘食。” 本文目录: Unity游戏开发 Unity游戏开发unity中国 嗨嗨嗨,我来啦。 这几天的川渝之旅已经圆满结束了,今天开始正常给大家更新: Unity…

Unity与UE,哪种游戏引擎适合你?

PlayStation vs Xbox,Mario vs Sonic,Unreal vs Unity?无论是游戏主机、角色还是游戏引擎,人们总是热衷于捍卫他们在游戏行业中的偏爱。 专注于游戏引擎,Unity和Unreal Engine(简称UE4)是目前市…

利用漏洞实现 Outlook 的 RCE:第 2 部分

## 攻击面 Outlook 要播放的声音文件是波形音频文件格式( WAV)。它通过接收声音文件路径的PlaySound函数播放。PlaySound将加载文件、解析它,然后调用soundOpen,后者将调用不同的波形函数,例如waveOutOpen。 WAV 文件充当多个音频编解码器的容器(或包装器)。编解码器是一…

Shire 0.5 发布:构建数据安全 RAG,充分整合研发资产

最近,我们发布了新版本的 Shire,在这个新的发布(Shire 0.5)里,你可以更好地融合本地研发资产,同时构建数据安全 RAG。在这次版本中,我们增加了: 对 SonarQube 的 issue 支持。可以直…

从0到1构建视频汇聚生态:EasyCVR视频汇聚平台流媒体协议支持的前瞻性布局

TSINGSEE青犀EasyCVR视频汇聚平台是一款基于云-边-端一体化架构的视频融合AI智能分析平台,广泛应用于工地、仓储、工厂、社区、校园、楼宇等多个领域。平台凭借其强大的数据接入、处理、转码及分发能力,在视频监控领域展现出显著的技术优势和应用前景。本…

python项目在linux中的启动脚本(shell脚本)

背景: 在linux环境,使用shell脚本,实现对某个服务的启动、停止功能。 shell脚本的功能: 启动(start):通过参数 start ,实现启动服务。如果该服务已经启动,给出已经启动…

松下弧焊机器人维修 控制柜故障 连接线修复

一、Panasonic焊接机器人控制柜与机器人的接线 机器人的控制箱,一定要配对使用。松下焊接机器人控制柜已经记忆了机器人的绝对原点(机器人位置控制原点)。 二、编码器电缆 (圆形连接器) 1. 接口的插头插座要注意,插头要插到插座中。 2. 用一手握住电缆&a…

《黑神话:悟空》发售后快手游戏笔记本电脑GMV日环比增长40%

一、美联储9月降息预期升温 昨夜美股三大股指在震荡中收涨,市场情绪受到美联储7月会议纪要提振。纪要显示,美联储官员普遍倾向于9月降息,多位官员认为当前利率水平已对经济构成限制。此消息推动美股上涨,并带动金价创新高&#xf…

鸿蒙HarmonyOS编程开发:TLS单向认证通讯示例

1.TLS简介 TLS(Transport Layer Security)协议的前身是SSL(Secure Socket Layer)安全套接层协议,由Netscape公司于1994年提出,是一套网络通信安全协议。IETF(The Internet Engineering Task Fo…

前端开发中的大屏布局方案:使用 rem 单位与动态设置 html 的 font-size

使用 rem 单位与动态设置 html 的 font-size 前言 随着设备尺寸的多样化,网页需要能够在不同大小的屏幕上提供良好的用户体验。传统的布局方式(如使用 px)在不同分辨率下可能会导致布局失真。为了解决这个问题,我们可以通过动态…

【UE5】基于摄像机距离逐渐剔除角色

效果 步骤 1. 新建一个工程,在内容浏览器中添加第三人称游戏内容包 2. 找到第三人称角色的材质实例“MI_Quinn_01”并打开 找到材质实例的父项材质“M_Mannequin” 打开材质“M_Mannequin” 在材质图表中添加如下节点 此时运行效果如文章开头所示。 参考视频&#…

flutter 中 ssl 双向证书校验

SSL 证书: 在处理 https 请求的时候,通常可以使用 中间人攻击的方式 获取 https 请求以及响应参数。应为通常我们是 SSL 单向认证,服务器并没有验证我们的客户端的证书。为了防止这种中间人攻击的情况。我么可以通过 ssl 双向认证的方式。即…

创意无限,尽在掌握:热门视频剪辑软件一览

我们记录生活、分享故事、传播信息用视频的频率越来越高了。而这些视频往往都是通过剪辑之后才能展示出当前的效果。那这次我们就来探索剪辑视频的时候都会用到什么工具吧。 1.福昕视频剪辑 连接直达>>https://www.pdf365.cn/foxit-clip/ 这是一款专为追求高效与创意…

【React】为什么Hooks不能出现在判断中

前言 在 React 中,Hooks 不能写在条件语句中,如下面这段代码点击button后则会报错。 import { useEffect, useState } from "react"export default () > {const [count, setCount] useState(0)if (count > 0) {useEffect(() > {co…

2-74 基于matlab的图像k-means聚类GUI

基于matlab的图像k-means聚类GUI,可对彩色图像进行Kmeans和meanshift进行聚类分析,生成最后的聚类图像以及聚类中心的迭代轨迹。程序已调通,可直接运行。 2-74 matlab GUI - 小红书 (xiaohongshu.com)