对于jsonp技术访问天气Demo感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍嘲笑鸡儿小,并为您提供关于@CosmosInput无法识别json的JsonProperty、ajax小demo
对于jsonp技术访问天气Demo感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍嘲笑鸡儿小,并为您提供关于@CosmosInput 无法识别 json 的 JsonProperty、ajax小demo---JSONP 跨域原理及简单应用、AJAX(七)jsonp实战--天气预报、Android-天气预报Demo-JSON数据解析的有用信息。
本文目录一览:- jsonp技术访问天气Demo(嘲笑鸡儿小)
- @CosmosInput 无法识别 json 的 JsonProperty
- ajax小demo---JSONP 跨域原理及简单应用
- AJAX(七)jsonp实战--天气预报
- Android-天气预报Demo-JSON数据解析
jsonp技术访问天气Demo(嘲笑鸡儿小)
jsonp技术访问天气Demo,该网站实现了返回数据为xml或json类型
注意:select*fromjsonwhereurl='..'要用空格隔开
http://query.yahooapis.com/v1/public/yql?q=select*fromjsonwhereurl='http://m.weather.com.cn/data/101010100.html'
//返回一个xml的文档树(object类型)
http://query.yahooapis.com/v1/public/yql?q=select*fromjsonwhereurl='http://m.weather.com.cn/data/101010100.html'&format=json
//将返回的xml的文档树(object类型)转变为json类型(object)
tianqi.jsp代码如下:
<%@pagepageEncoding="utf-8"%>
<%@tagliburi="/struts-tags"prefix="s"%>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title>注册</title>
<Metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/>
<scripttype="text/javascript"src="../js/jquery-1.4.3.js"></script>
</head>
<body>
<fontcolor='red'>天气预报demo界面</font>
<divid="content">
文本框内容
</div>
<script>
$(function(){
$.getJSON("http://query.yahooapis.com/v1/public/yql",
{q:"select*fromjsonwhereurl='http://m.weather.com.cn/data/101010100.html'",format:"json"},
function(data){var$content=$("#content")if(data.query.results){varresult=JSON.stringify(data.query.results);$content.text(result);varobj=eval('('+result+')');alert(obj.weatherinfo.city);}else{$content.text('nosuchcode:'+code);}});});</script></body><script></script></html>
@CosmosInput 无法识别 json 的 JsonProperty
如何解决@CosmosInput 无法识别 json 的 JsonProperty?
下午好:
我目前正在创建一个带有 @CosmosInput 的 Azure 函数。我有这些豆子:
public class Product {
private String id;
@JsonAlias("Name1")
private String name;
private Tipo tipo;
// get y set
}
和
public class Type1 {
private String id;
@JsonAlias("Name2")
private String name;
public String getId() {
return id;
}
}
我在 MongoDB 或 CosmosDB 中的对象:
{
"id": "1","Name1": "Product 1","tipo": {
"id": "T1","Name2": "Type 1"
}
}
但是当我运行该函数时,它无法识别对象“Name1”和“Name2”。功能是这样的:
@FunctionName("example")
public String run(@TimerTrigger(name = "clock",schedule = "expression") String clock,@CosmosDBInput(name = "items",databaseName = "example",collectionName = "Product",connectionStringSetting = "connectionZ") Optional<List<Product>> products
final ExecutionContext context) {
for(Product p: products.get()){
System.out.println("Name: " + p.getName());
}
}
字段“名称”给我带来了空值。
拜托,我不知道你能不能告诉我可能遗漏了什么。
谢谢。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
ajax小demo---JSONP 跨域原理及简单应用
一.jsonp
Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
因为同源策略,(它是由netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。)我们不能从不同的域(网站)访问数据,而jsonp就是用来实现这种不能跨域请求数据。
二.jsonp原理:
在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。然而,JSONP就是通过script节点src属性来实现调用跨域的请求。通过动态的创建script标签,当我们通过JSONP模式请求跨域资源时,服务器返回给客户端一段javascript代码,这段javascript代码自动调用客户端回调函数。
三.实例
当使用ajax本地调用url='http://127.0.0.1/ajax/json/test.php?data='+jsonobj+"&r="+Math.random();会出现下面的错误:不能跨域请求
使用jsonp就可以解决这个问题:具体代码如下:
<script> varresult=false; functioncheck(){ if(resultform()){ returntrue; } else{ returnfalse; } } functioncheckform(){ varusernameobj=document.getElementById('username').value; varusernumobj=document.getElementById('usernum').value; vardata={username:usernameobj,usernum:usernumobj}; varjsonobj=JSON.stringify(data); url='http://127.0.0.1/ajax/json/test.PHP?data='+jsonobj+"&r="+Math.random()+"&callbackname=jp"; //动态添加script标签 varscripttag=document.createElement("script"); scripttag.setAttribute("src",url); document.body.appendChild(scripttag); } //客户端回调函数 varjp=function(data){ vartips=document.getElementById('tips'); if(data['username']=="11"){ tips.innerHTML="<h1>你输入的名字是:"+data['username']+"</h1>"; result=true; } else{ tips.innerHTML="<h1>你输入的有误</h1>"; result=false; } resultform(); } functionresultform(){ if(result){ returntrue; } else{ alert("您输入的有误"); returnfalse; } } </script> PHP页面代码: <?PHP $data=json_decode($_GET['data'],true); $callbackname=$_GET['callbackname']; echo$callbackname."(".json_encode($data).")"; ?>
效果图:
AJAX(七)jsonp实战--天气预报
一、案例
本次要做的案例的是使用jsonp制作一个查询天气情况的网页,我会从如何抓取数据接口,到一步一步完成这个案例来详细讲解。
这个页面样式非常简单,截图如下。用户需要先选择一个城市,然后点击查看天气,那么最近5天的天气数据,就会展示到下面。
二、数据从何而来
当然我们不可能自己建气象站,我们只有通过互联网拿到别人“分享”给我们的数据接口,然后通过这个数据接口获取全国的气象数据。这样我们就必须使用jsonp了,因为提供气象数据服务的api,其所在的域名肯定跟我们自己的应用程序不是一个域名。
那么问题来了,我们如何知道哪里有api提供气象数据服务的?这个就要多观察多积累了。比如现在很多人的电脑上都会安装360,一般360杀毒在安装时候会篡改你的浏览器主页为“hao360”这个网站,那么你打开网页,每次都会看到这样的画面。
这个网站在非常显眼的地方提供了一个查看天气的模块。难道360还开着气象站?如果不是,那我们只要看看它是如何搞到数据的,我们就能如法炮制了。
一般你可以这样做:
1.在气象模块上点鼠标右键->审查元素。去看看他的结构
2.打开开发者选项工具窗口,点击Network(网络)选项卡,然后去查看请求报文,这样就能找到气象数据从哪儿来了。
不过,如果你没有经验,你会被请求报文列表中的数据给吓住,因为实在是太多了,至少不下300条请求项。那我们怎么去找真正需要的那个请求呢?
试想,这个hao360也不可能自己弄个气象站,所以它必然也是抓取的第三方api,所以也必然是通过jsonp的形式来实现的。那么我们只需要在所有的请求报文中按type这一列排下序,然后就只管看请求类型是script的那些项。这样一下就把范围缩小了很多很多。
最后我们找到,这里的请求url是:https://cdn.weather.hao.360.cn/sed_api_weather_info.php?code=101180201&app=hao360&_jsonp=__jsonp3__
简单说明下这个url的参数
1.code:要查询的城市编码,这个可以百度
2._jsonp:你自己定义的回调函数的名字。
3.其他的参数都无关紧要,至少对本案例来说是这样。
在浏览器里打开这个链接,你看到的结果是这样的:
当然,我只截取了一小部分。不过已经可以看出了,这是一个典型的jsonp跨域访问。
然后,我把数据copy出来,贴到sublime中,格式化之后,数据是这个样子的。
1 { 2 "pubdate": "2018-06-25", 3 "pubtime": "16:44:10", 4 "time": 1529916250, 5 "area": [ 6 ["\u6cb3\u5357","18"], 7 ["\u5b89\u9633","1802"], 8 ["\u5b89\u9633","101180201"] 9 ],10 "weather": [{ 11 "date": "2018-06-25",12 "info": { 13 "dawn": ["2","\u9634","24","\u5357\u98ce","\u5fae\u98ce","19:44"],14 "day": ["8","\u4e2d\u96e8","27","\u5317\u98ce","05:07"],15 "night": ["8","22","\u897f\u98ce","19:44"] 16 } 17 },{ 18 "date": "2018-06-26",19 "info": { 20 "dawn": ["8",21 "day": ["7","\u5c0f\u96e8","28",22 "night": ["1","\u591a\u4e91","19:44"] 23 } 24 },{ 25 "date": "2018-06-27",26 "info": { 27 "dawn": ["1",28 "day": ["0","\u6674","37","05:08"],29 "night": ["0","3-5\u7ea7","19:44"] 30 } 31 },{ 32 "date": "2018-06-28",33 "info": { 34 "dawn": ["0",35 "day": ["0","36","\u4e1c\u5317\u98ce",36 "night": ["1","21","19:45"] 37 } 38 },{ 39 "date": "2018-06-29",40 "info": { 41 "dawn": ["1","19:45"],42 "day": ["1","35","\u4e1c\u5357\u98ce",43 "night": ["1","19:45"] 44 } 45 }], 46 。。。。。。 47 }
简单解释下数据:
1.这里只截取了数据的一部分,只保留了我们案例中需要用到的那一小部分,感兴趣的自己去研究吧。
2.显然,这个数据是js中的,json格式数据。
3.本案例中用到的气象数据,是在这个json对象的“weather”属性中。这个属性的值是一个js数组,数组一共有5个元素,每个元素又是一个json对象,每个json对象都代表了一天的天气情况。
三、案例的HTML结构
先看下页面的HTML结构
<!DOCTYPE html> <html lang="en"> <head> <Meta charset="UTF-8"> <Meta name="viewport" content="width=device-width,initial-scale=1.0"> <Meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>天气预报-hao360接口</title> <link rel="stylesheet" href="css/weather.css"> </head> <body> <div class="wt_container"> <div class="city"> <select id="selCity"> <option value="101180201">大安阳</option> <option value="101010100">北京</option> <option value="101180101">郑州</option> <option value="101250101">长沙</option> <option value="101050101">哈尔滨</option> <option value="101130101">乌鲁木齐</option> <option value="101280101">广州</option> </select> <button id="btn">查看天气</button> </div> <div class="weather"> <ul id="wtInfo"> <!-- <li> <h2>25日</h2> <div> <h3>白天天气</h3> <p>天气:</p> <p>温度</p> <p>风向</p> <p>风速</p> </div> <div> <h3>夜间天气</h3> <p>天气:</p> <p>温度</p> <p>风向</p> <p>风速</p> </div> </li> --> </ul> </div> </div> </body> </html>
大家都看得懂,简单说明下:
1.select标签中的每个选项都有一个value值,这个值对应的城市编码,这个编码是国家标准编码,不是自己随便乱写的,我是从百度出来然后写死到页面上的。当然,网上也有关于提供省市编码查询的api,你完全可以根据本案例所讲的方法,结合之前AJAX中讲的省市联动的案例,把这里城市的选择做成活的。我这里为了简单起见,随便从网上扒了几个城市,把城市的code拷贝了一下就写死到HTML了。目的只是为了让例子别太复杂。
2.由于我们拿到的数据是5天的数据,所以我们用一个<ul id = "wtInof">标签来展示所有的查询到的5天的天气,每天的天气用一个li包住。HTML中注释掉的部分就是模拟数据。
我们在js部分,只需要通过jsonp请求道数据,然后按照模拟数据的格式,填充到ul里就行了。
四、案例的js部分
直接看代码
1 <script src="js/jquery-3.3.1.js"></script> 2 <script> 3 function callback(data){ 4 //1.清空ul#wtInfo 5 $("#wtInfo").html(""); 6 //2.呈现数据 7 var wt = data.weather; 8 $.each(wt,function(index,ele){ 9 var date = ele.date; 10 var day = ele.info.day; 11 var night = ele.info.night; 12 var tag = "<li>"; 13 tag += "<h2>" + date + "</h2>"; 14 tag += "<div class=‘day‘>"; 15 tag += "<h3>白天天气</h3>"; 16 tag += "<p>天气:" + day[1] + "</p>"; 17 tag += "<p>温度:" + day[2] + "</p>"; 18 tag += "<p>风向:" + day[3] + "</p>"; 19 tag += "<p>风速:" + day[4] + "</p>"; 20 tag += "</div>"; 21 tag += "<div class=‘night‘>"; 22 tag += "<h3>夜间天气</h3>"; 23 tag += "<p>天气:" + night[1] + "</p>"; 24 tag += "<p>温度:" + night[2] + "</p>"; 25 tag += "<p>风向:" + night[3] + "</p>"; 26 tag += "<p>风速:" + night[4] + "</p>"; 27 tag += "</div>"; 28 tag += "</li>"; 29 $("#wtInfo").append(tag); 30 }); 31 } 32 $(function () { 33 $("#btn").on("click",function () { 34 var cityCode = $("#selCity option:selected").val(); 35 var url = 36 ‘https://cdn.weather.hao.360.cn/sed_api_weather_info.PHP?app=hao360&_jsonp=callback&code=‘ + 37 cityCode; 38 $("body").append($("<script src=‘" + url + "‘><script>")); 39 }) 40 }) 41 </script>
代码解释:
1.这用到了jQuery,所以第1行代码先引入了jQuery包
2.jsonp的原理是通过<script>标签发出请求,而本例中不希望一打开网页就显示某一个城市的天气数据,而是要先选择一个,然后点击查询按钮,才发出请求,得到气象数据, 展示数据。
3.所以我们的思路是:肯定不能在页面上写死那个做jsonp请求的<script src = "......">标签。我们的做法是,当点击按钮时,我们动态的获取到所选select标签中城市的code,然后拼写出待请求的url,最后在文档(document)的body标签底部,动态添加这个做jsonp请求的<script src = "......">标签。
4.代码中定义的function callback(data)函数,就是用来做回调函数的,在这个回调函数中,主要功能就是解析json数据,然后填充到ul中。本身代码逻辑不复杂,就是拼写每个li,以及li里边的各项元素有点费事而已。
五、后记
这个案例,到这里就结束了。我再补充2点:
1.这个案例中需要大量拼写HTML标签代码,这么做是相当费时费力的,而且容易出错;一旦开发一个复杂点的页面,这么做是非常痛苦的。如何改进?我们可以使用模板技术。前端模板插件很多,最流行的前端模板就是art-template.js,大家可以从网上下载。我在这里给出使用该模板改造本例后的js代码,具体这个art-template怎么用,大家看看他官服的demo就一目了然,非常简单。
<script src="js/template.js"></script> <script id="weatherTemp" type="text/html"> <li> <h2><%= date %></h2> <div> <h3>白天天气</h3> <% for(var i=1; i < info.day.length; i++){%> <p><%= info.day[i]%></p> <% }%> </div> <div> <h3>夜间天气</h3> <% for(var i=1; i < info.night.length; i++){%> <p><%= info.night[i]%></p> <% }%> </div> </li> </script> <script> function callback(data) { //1.清空ul#wtInfo $("#wtInfo").html(""); //2.呈现数据 var wt = data.weather; $.each(wt,function (index,ele) { var html = template("weatherTemp",ele) $("#wtInfo").append(html); }); } $(function () { $("#btn").on("click",function () { var cityCode = $("#selCity option:selected").val(); var url = ‘https://cdn.weather.hao.360.cn/sed_api_weather_info.PHP?app=hao360&_jsonp=callback&code=‘ + cityCode; $("body").append($("<script src=‘" + url + "‘><script>")); }) }) </script>
2.如果我们每次都去分析别人的报文,那将是一个非常痛苦的过程。好在现在有专业的,专门提供数据服务的web api提供商,比如“聚合数据”,百度api商店等等,还有很多,大家可以去网上搜索下。其中有免费的,有付费的。比如聚合数据,申请账号是免费的,提供的服务有的免费,有的付费,不过即使是付费的,也可以免费使用1000次,对于我们学习来说1000次够玩了。
Android-天气预报Demo-JSON数据解析
在上两篇博客,Android-解析JSON数据(JSON对象/JSON数组),Android-Gson解析JSON数据(JSON对象/JSON数组),是介绍了解析本地文件里面的JSON数据;
Android去访问外网的天气预报接口,解析天气预报返回的JSON数据;
天气API JSON返回方式
我测试一下请求北京的天气,链接为:https://www.sojson.com/open/api/weather/json.shtml?city=北京
返回成功状态为:200
,失败为非200
天气API JSON返回方式(成功)
访问天气预报JSON数据:
https://www.sojson.com/open/api/weather/json.shtml?city=北京
天气预报返回的JSON数据:
{
"tips":"注意:当前API已经停用,新API没有次数限制,详情查看===>https://www.sojson.com/blog/305.html。",
"date":"20181224",
"message":"Success !",
"status":200,
"city":"北京当前API已经停用,新API没有次数限制,详情查看:https://www.sojson.com/blog/305.html",
"data":{
"shidu":"50%",
"pm25":81,
"pm10":133,
"quality":"轻度污染",
"wendu":"-13",
"ganmao":"儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼",
"yesterday":{
"date":"23日星期日",
"sunrise":"07:33",
"high":"高温 0.0℃",
"low":"低温 -9.0℃",
"sunset":"16:53",
"aqi":47,
"fx":"北风",
"fl":"3-4级",
"type":"晴",
"notice":"愿你拥有比阳光明媚的心情"
},
"forecast":[
{
"date":"24日星期一",
"sunrise":"07:33",
"high":"高温 2.0℃",
"low":"低温 -8.0℃",
"sunset":"16:54",
"aqi":62,
"fx":"西南风",
"fl":"<3级",
"type":"晴",
"notice":"愿你拥有比阳光明媚的心情"
},
{
"date":"25日星期二",
"sunrise":"07:34",
"high":"高温 3.0℃",
"low":"低温 -8.0℃",
"sunset":"16:54",
"aqi":90,
"fx":"北风",
"fl":"3-4级",
"type":"晴",
"notice":"愿你拥有比阳光明媚的心情"
},
{
"date":"26日星期三",
"sunrise":"07:34",
"high":"高温 -2.0℃",
"low":"低温 -9.0℃",
"sunset":"16:55",
"aqi":27,
"fx":"东北风",
"fl":"<3级",
"type":"晴",
"notice":"愿你拥有比阳光明媚的心情"
},
{
"date":"27日星期四",
"sunrise":"07:34",
"high":"高温 -3.0℃",
"low":"低温 -11.0℃",
"sunset":"16:55",
"aqi":27,
"fx":"北风",
"fl":"3-4级",
"type":"多云",
"notice":"阴晴之间,谨防紫外线侵扰"
},
{
"date":"28日星期五",
"sunrise":"07:35",
"high":"高温 -3.0℃",
"low":"低温 -10.0℃",
"sunset":"16:56",
"aqi":31,
"fx":"北风",
"fl":"3-4级",
"type":"晴",
"notice":"愿你拥有比阳光明媚的心情"
}
]
},
"count":2
}
加权限:
<!-- 访问网络是危险的行为,所以需要加入权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 外置存储Sdcard 读取权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 外置存储Sdcard 写入权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
定义 Forecast 实体Bean:
package liudeli.mynetwork01.entity;
/**
* {
* "date":"24日星期一",
* "sunrise":"07:33",
* "high":"高温 2.0℃",
* "low":"低温 -8.0℃",
* "sunset":"16:54",
* "aqi":62,
* "fx":"西南风",
* "fl":"<3级",
* "type":"晴",
* "notice":"愿你拥有比阳光明媚的心情"
* }
*/
public class Forecast {
private String date;
private String sunrise;
private String high;
private String low;
private String sunset;
private int api;
private String fx;
private String fl;
private String type;
private String notice;
public Forecast() {
}
public Forecast(String date, String sunrise, String high, String low, String sunset, int api, String fx, String fl, String type, String notice) {
this.date = date;
this.sunrise = sunrise;
this.high = high;
this.low = low;
this.sunset = sunset;
this.api = api;
this.fx = fx;
this.fl = fl;
this.type = type;
this.notice = notice;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getSunrise() {
return sunrise;
}
public void setSunrise(String sunrise) {
this.sunrise = sunrise;
}
public String getHigh() {
return high;
}
public void setHigh(String high) {
this.high = high;
}
public String getLow() {
return low;
}
public void setLow(String low) {
this.low = low;
}
public String getSunset() {
return sunset;
}
public void setSunset(String sunset) {
this.sunset = sunset;
}
public int getApi() {
return api;
}
public void setApi(int api) {
this.api = api;
}
public String getFx() {
return fx;
}
public void setFx(String fx) {
this.fx = fx;
}
public String getFl() {
return fl;
}
public void setFl(String fl) {
this.fl = fl;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
@Override
public String toString() {
return "Forecast{" +
"date=''" + date + ''\'''' +
", sunrise=''" + sunrise + ''\'''' +
", high=''" + high + ''\'''' +
", low=''" + low + ''\'''' +
", sunset=''" + sunset + ''\'''' +
", api=" + api +
", fx=''" + fx + ''\'''' +
", fl=''" + fl + ''\'''' +
", type=''" + type + ''\'''' +
", notice=''" + notice + ''\'''' +
''}'';
}
}
具体实现代码:
package liudeli.mynetwork01;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import liudeli.mynetwork01.entity.Forecast;
public class WeatherActivity extends Activity {
private final String TAG = WeatherActivity.class.getSimpleName();
private ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_weather);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("提示");
progressDialog.setMessage("正在获取网络上的天气预报信息");
progressDialog.show();
downloadWeatherDataInfo();
saveJSONToFile();
}
private void saveJSONToFile() {
// 保存文件到Sdcard
File file = new File(Environment.getExternalStorageDirectory(), "weather.txt");
try {
Writer writer = new FileWriter(file);
writer.write("{\n" +
" \"tips\":\"注意:当前API已经停用,新API没有次数限制,详情查看===>https://www.sojson.com/blog/305.html。\",\n" +
" \"date\":\"20181224\",\n" +
" \"message\":\"Success !\",\n" +
" \"status\":200,\n" +
" \"city\":\"北京当前API已经停用,新API没有次数限制,详情查看:https://www.sojson.com/blog/305.html\",\n" +
" \"data\":{\n" +
" \"shidu\":\"50%\",\n" +
" \"pm25\":81,\n" +
" \"pm10\":133,\n" +
" \"quality\":\"轻度污染\",\n" +
" \"wendu\":\"-13\",\n" +
" \"ganmao\":\"儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼\",\n" +
" \"yesterday\":{\n" +
" \"date\":\"23日星期日\",\n" +
" \"sunrise\":\"07:33\",\n" +
" \"high\":\"高温 0.0℃\",\n" +
" \"low\":\"低温 -9.0℃\",\n" +
" \"sunset\":\"16:53\",\n" +
" \"aqi\":47,\n" +
" \"fx\":\"北风\",\n" +
" \"fl\":\"3-4级\",\n" +
" \"type\":\"晴\",\n" +
" \"notice\":\"愿你拥有比阳光明媚的心情\"\n" +
" },\n" +
" \"forecast\":[\n" +
" {\n" +
" \"date\":\"24日星期一\",\n" +
" \"sunrise\":\"07:33\",\n" +
" \"high\":\"高温 2.0℃\",\n" +
" \"low\":\"低温 -8.0℃\",\n" +
" \"sunset\":\"16:54\",\n" +
" \"aqi\":62,\n" +
" \"fx\":\"西南风\",\n" +
" \"fl\":\"<3级\",\n" +
" \"type\":\"晴\",\n" +
" \"notice\":\"愿你拥有比阳光明媚的心情\"\n" +
" },\n" +
" {\n" +
" \"date\":\"25日星期二\",\n" +
" \"sunrise\":\"07:34\",\n" +
" \"high\":\"高温 3.0℃\",\n" +
" \"low\":\"低温 -8.0℃\",\n" +
" \"sunset\":\"16:54\",\n" +
" \"aqi\":90,\n" +
" \"fx\":\"北风\",\n" +
" \"fl\":\"3-4级\",\n" +
" \"type\":\"晴\",\n" +
" \"notice\":\"愿你拥有比阳光明媚的心情\"\n" +
" },\n" +
" {\n" +
" \"date\":\"26日星期三\",\n" +
" \"sunrise\":\"07:34\",\n" +
" \"high\":\"高温 -2.0℃\",\n" +
" \"low\":\"低温 -9.0℃\",\n" +
" \"sunset\":\"16:55\",\n" +
" \"aqi\":27,\n" +
" \"fx\":\"东北风\",\n" +
" \"fl\":\"<3级\",\n" +
" \"type\":\"晴\",\n" +
" \"notice\":\"愿你拥有比阳光明媚的心情\"\n" +
" },\n" +
" {\n" +
" \"date\":\"27日星期四\",\n" +
" \"sunrise\":\"07:34\",\n" +
" \"high\":\"高温 -3.0℃\",\n" +
" \"low\":\"低温 -11.0℃\",\n" +
" \"sunset\":\"16:55\",\n" +
" \"aqi\":27,\n" +
" \"fx\":\"北风\",\n" +
" \"fl\":\"3-4级\",\n" +
" \"type\":\"多云\",\n" +
" \"notice\":\"阴晴之间,谨防紫外线侵扰\"\n" +
" },\n" +
" {\n" +
" \"date\":\"28日星期五\",\n" +
" \"sunrise\":\"07:35\",\n" +
" \"high\":\"高温 -3.0℃\",\n" +
" \"low\":\"低温 -10.0℃\",\n" +
" \"sunset\":\"16:56\",\n" +
" \"aqi\":31,\n" +
" \"fx\":\"北风\",\n" +
" \"fl\":\"3-4级\",\n" +
" \"type\":\"晴\",\n" +
" \"notice\":\"愿你拥有比阳光明媚的心情\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"count\":2\n" +
"}\n" +
"\n");
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 访问https://www.sojson.com/open/api/weather/json.shtml?city=北京
* 获取北京天气预报数据信息
*/
public void downloadWeatherDataInfo() {
new Thread(){
@Override
public void run() {
super.run();
try {
// 把字符串地址包装成网络地址
URL url = new URL("https://www.sojson.com/open/api/weather/json.shtml?city=北京");
// 打开连接对象
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
// 设置连接超时时长
httpURLConnection.setConnectTimeout(5000);
// 设置请求方式Get
httpURLConnection.setRequestMethod("GET");
// 注意:是执行httpURLConnection.getResponseCode()的时候,才开始向服务器发送请求
int code = httpURLConnection.getResponseCode();
Log.d(TAG, ">>> run: code:" + code);
/**
* 现在由于访问受限,只能模拟去读文件里面的JSON数据,实际上和读取网络数据一模一样
*/
code = 200;
if (code == HttpURLConnection.HTTP_OK) {
File file = new File(Environment.getExternalStorageDirectory(), "weather.txt");
if (!file.exists()) {
mHandler.sendEmptyMessageDelayed(REQUEST_ERROR, 1500); // delayMillis 是为了模仿网络弱
return;
}
InputStream fis = new FileInputStream(file);
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(bytes, 0, bytes.length);
Message message = mHandler.obtainMessage();
message.what = REQUEST_SUCCESS;
message.obj = new String(baos.toByteArray());
mHandler.sendMessageDelayed(message, 1500); // delayMillis 是为了模仿网络弱
} else {
mHandler.sendEmptyMessageDelayed(REQUEST_ERROR, 1500); // delayMillis 是为了模仿网络弱
}
} catch (Exception e) {
e.printStackTrace();
mHandler.sendEmptyMessage(REQUEST_ERROR);
}
}
}.start();
}
private final int REQUEST_SUCCESS = 200;
private final int REQUEST_ERROR = 400;
private final int CLOSE = 1000;
/**
* Handler与子线程通讯
*/
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case REQUEST_ERROR:
progressDialog.setMessage("请求错误!");
mHandler.sendEmptyMessageDelayed(CLOSE, 1500); // delayMillis 是为了模仿网络弱
Log.d(TAG, "请求错误!");
break;
case REQUEST_SUCCESS:
progressDialog.setMessage("恭喜,请求成功");
String successResult = (String) msg.obj;
handlerSuccessMethod(successResult);
mHandler.sendEmptyMessageDelayed(CLOSE, 1500); // delayMillis 是为了模仿网络弱
Log.d(TAG, "恭喜,请求成功");
break;
case CLOSE:
progressDialog.dismiss();
Log.d(TAG, "CLOSE");
break;
}
}
};
/**
* 请求成功后,拿到JSON数据
* @param successResult JSON数据
*/
private void handlerSuccessMethod(String successResult) {
Log.d(TAG, "handlerSuccessMethod successResult:" + successResult);
try{
// 整体最大的JSON对象
JSONObject jsonObjectALL = new JSONObject(successResult);
Log.d(TAG, "解析后的数据:tips:" + jsonObjectALL.optString("tips", null));
Log.d(TAG, "解析后的数据:date:" + jsonObjectALL.optString("date", null));
Log.d(TAG, "解析后的数据:message:" + jsonObjectALL.optString("message", null));
Log.d(TAG, "解析后的数据:status:" + jsonObjectALL.optString("status", null)); // 真实开发中要判断status==200
Log.d(TAG, "解析后的数据:city:" + jsonObjectALL.optString("city", null));
// data JSON 对象
String data = jsonObjectALL.optString("data", null);
JSONObject dataJSONObject = new JSONObject(data);
Log.d(TAG, "解析后的数据:shidu:" + dataJSONObject.optString("shidu", null));
Log.d(TAG, "解析后的数据:pm25:" + dataJSONObject.optString("pm25", null));
Log.d(TAG, "解析后的数据:pm10:" + dataJSONObject.optString("pm10", null));
Log.d(TAG, "解析后的数据:quality:" + dataJSONObject.optString("quality", null));
Log.d(TAG, "解析后的数据:wendu:" + dataJSONObject.optString("wendu", null));
Log.d(TAG, "解析后的数据:ganmao:" + dataJSONObject.optString("ganmao", null));
// yesterday JSON 对象
String yesterday = dataJSONObject.optString("yesterday");
JSONObject yesterdayJSONObject = new JSONObject(yesterday);
Log.d(TAG, "解析后的数据:date:" + yesterdayJSONObject.optString("date", null));
Log.d(TAG, "解析后的数据:sunrise:" + yesterdayJSONObject.optString("sunrise", null));
Log.d(TAG, "解析后的数据:high:" + yesterdayJSONObject.optString("high", null));
Log.d(TAG, "解析后的数据:low:" + yesterdayJSONObject.optString("low", null));
Log.d(TAG, "解析后的数据:sunset:" + yesterdayJSONObject.optString("sunset", null));
Log.d(TAG, "解析后的数据:aqi:" + yesterdayJSONObject.optString("aqi", null));
Log.d(TAG, "解析后的数据:fx:" + yesterdayJSONObject.optString("fx", null));
Log.d(TAG, "解析后的数据:fl:" + yesterdayJSONObject.optString("fl", null));
Log.d(TAG, "解析后的数据:type:" + yesterdayJSONObject.optString("type", null));
Log.d(TAG, "解析后的数据:notice:" + yesterdayJSONObject.optString("notice", null));
// forecast JSON [数组] 这种有规律的 JSON数组,我决定用 Gson 来得到集合
// 注意:forecast 的标记key 是data
String forecastJSONArray = dataJSONObject.optString("forecast", null);
Gson gson = new Gson();
List<Forecast> list = gson.fromJson(forecastJSONArray, new TypeToken<List<Forecast>>(){}.getType());
for (Forecast f : list) {
Log.d(TAG, "解析后的数据 f.toString:" + f.toString());
}
// 解析最后一个字段count,count的标记key是整个最大对象
int count = jsonObjectALL.optInt("count", 0);
Log.d(TAG, "解析后的数据 count:" + count);
}catch (Exception e) {
e.printStackTrace();
}
}
}
解析后的结果:
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:tips:注意:当前API已经停用,新API没有次数限制,详情查看===>https://www.sojson.com/blog/305.html。
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:date:20181224
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:message:Success !
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:status:200
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:city:北京当前API已经停用,新API没有次数限制,详情查看:https://www.sojson.com/blog/305.html
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:shidu:50%
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:pm25:81
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:pm10:133
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:quality:轻度污染
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:wendu:-13
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:ganmao:儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:date:23日星期日
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:sunrise:07:33
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:high:高温 0.0℃
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:low:低温 -9.0℃
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:sunset:16:53
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:aqi:47
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:fx:北风
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:fl:3-4级
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:type:晴
12-24 08:02:59.486 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据:notice:愿你拥有比阳光明媚的心情
12-24 08:02:59.523 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据 f.toString:Forecast{date=''24日星期一'', sunrise=''07:33'', high=''高温 2.0℃'', low=''低温 -8.0℃'', sunset=''16:54'', api=0, fx=''西南风'', fl=''<3级'', type=''晴'', notice=''愿你拥有比阳光明媚的心情''}
12-24 08:02:59.523 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据 f.toString:Forecast{date=''25日星期二'', sunrise=''07:34'', high=''高温 3.0℃'', low=''低温 -8.0℃'', sunset=''16:54'', api=0, fx=''北风'', fl=''3-4级'', type=''晴'', notice=''愿你拥有比阳光明媚的心情''}
12-24 08:02:59.523 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据 f.toString:Forecast{date=''26日星期三'', sunrise=''07:34'', high=''高温 -2.0℃'', low=''低温 -9.0℃'', sunset=''16:55'', api=0, fx=''东北风'', fl=''<3级'', type=''晴'', notice=''愿你拥有比阳光明媚的心情''}
12-24 08:02:59.523 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据 f.toString:Forecast{date=''27日星期四'', sunrise=''07:34'', high=''高温 -3.0℃'', low=''低温 -11.0℃'', sunset=''16:55'', api=0, fx=''北风'', fl=''3-4级'', type=''多云'', notice=''阴晴之间,谨防紫外线侵扰''}
12-24 08:02:59.523 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据 f.toString:Forecast{date=''28日星期五'', sunrise=''07:35'', high=''高温 -3.0℃'', low=''低温 -10.0℃'', sunset=''16:56'', api=0, fx=''北风'', fl=''3-4级'', type=''晴'', notice=''愿你拥有比阳光明媚的心情''}
12-24 08:02:59.523 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 解析后的数据 count:2
12-24 08:02:59.523 5179-5179/liudeli.mynetwork01 D/WeatherActivity: 恭喜,请求成功
12-24 08:03:01.076 5179-5179/liudeli.mynetwork01 D/WeatherActivity: CLOSE
今天关于jsonp技术访问天气Demo和嘲笑鸡儿小的讲解已经结束,谢谢您的阅读,如果想了解更多关于@CosmosInput 无法识别 json 的 JsonProperty、ajax小demo---JSONP 跨域原理及简单应用、AJAX(七)jsonp实战--天气预报、Android-天气预报Demo-JSON数据解析的相关知识,请在本站搜索。
本文标签: