1.0版本的功能:
后台方面:

1.将从接口拿到的json转为pojo。
2.使用Redis缓存提升应用的并发访问能力。
3.Quartz Schedule定时获取天气数据存入缓存进一步提升并发访问能力。

前端方面:

拿到数据传到小程序界面(直男的审美做出来的界面实在太丑了,1.0版本就先这样吧)

后台

步骤1(基础功能)

1.先实现最基本功能,将从接口拉到的数据转为实体pojo。这里使用到了Apache HttpClient,它的作用主要是第三方接口发送web请求。加入它的依赖即可使用。

     <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version></dependency>

2.json数据格式为下图,根据其构建处各个pojo,这样不列出各个pojo。第三方接口为"http://wthrcdn.etouch.cn/weather_mini?city=",是个完全免费的接口。

{"data": {"yesterday": {"date": "18日星期二","high": "高温 6℃","fx": "南风","low": "低温 -7℃","fl": "<![CDATA[<3级]]>","type": "多云"},"city": "榆林","forecast": [{"date": "19日星期三","high": "高温 7℃","fengli": "<![CDATA[<3级]]>","low": "低温 -6℃","fengxiang": "东南风","type": "晴"},{"date": "20日星期四","high": "高温 4℃","fengli": "<![CDATA[5-6级]]>","low": "低温 -7℃","fengxiang": "西北风","type": "多云"},{"date": "21日星期五","high": "高温 2℃","fengli": "<![CDATA[6-7级]]>","low": "低温 -9℃","fengxiang": "西北风","type": "多云"},{"date": "22日星期六","high": "高温 6℃","fengli": "<![CDATA[3-4级]]>","low": "低温 -2℃","fengxiang": "东南风","type": "晴"},{"date": "23日星期天","high": "高温 11℃","fengli": "<![CDATA[3-4级]]>","low": "低温 -2℃","fengxiang": "东南风","type": "晴"}],"ganmao": "天气寒冷,且昼夜温差很大,极易发生感冒。请特别注意增加衣服保暖防寒。","wendu": "3"},"status": 1000,"desc": "OK"
}

3.关键的service层的功能实现,使用spring中一个RestTemplate,RestTemplate就相当于封装了一个Rest客户端。将json字符串转为对象需要使用jackson中的mapperObject。展示下service层的核心代码。

    private WeatherResponse doGetWeather(String uri){ResponseEntity<String> respString = restTemplate.getForEntity(uri,String.class);ObjectMapper mapper = new ObjectMapper();WeatherResponse resp = null;String strBody = null;if (respString.getStatusCodeValue() == 200){strBody = respString.getBody();}try {resp = mapper.readValue(strBody,WeatherResponse.class);} catch (IOException e) {e.printStackTrace();}return resp;}

4.编写controller层,和配置类。controller层就非常简单不做展示,关键得对Rest进行配置。配置一下RestTemplate对classpath中的HttpClient进行一个具体实现。

@Configuration
public class RestConfiguration {@Autowiredprivate RestTemplateBuilder builder;@Beanpublic RestTemplate restTemplate(){return builder.build();}}

这时就可以先进行一下测试了,如果可以访问到数据的话再进行下一步缓存的实现。

步骤2(Redis缓存)

1.添加Redis依赖

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>1.5.3.RELEASE</version></dependency>

添加Redis依赖的时候,不知道到底是网络问题(老家网太差了)还是Redis版本与springboot版本有冲突,当时springboot 版本2.几导Redis2.几的包就导不进来,换成了Redis1.5.3.RELEASE有成功导入。这个问题等回到家网络好了再研究。

2.再导入个日志的依赖,同时还需要去掉web依赖中本身的日志
     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency>

3.配置Redis的application.properties,并且开启redis服务,打开redis可视化界面。

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.timeout=120000


点击redis.server.exe开启redis。

4.先查缓存,缓存有的从缓存中取,缓存中没有的从第三方拿。

    private WeatherResponse doGetWeather(String uri){String key = uri;String strBody = null;ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();ObjectMapper mapper = new ObjectMapper();WeatherResponse resp = null;//先查缓存,缓存中有的从缓存中取出if (stringRedisTemplate.hasKey(key)){LOGGER.info("Redis has data" + uri);strBody = ops.get(key);}else {LOGGER.info("Redis dose't has data" + uri);//缓存中没有,再调服务接口来获取ResponseEntity<String> respString = restTemplate.getForEntity(uri,String.class);if (respString.getStatusCodeValue() == 200){strBody = respString.getBody();}//数据写入缓存ops.set(key,strBody,TIME_OUT, TimeUnit.SECONDS);}try {resp = mapper.readValue(strBody,WeatherResponse.class);} catch (IOException e) {LOGGER.info("error" + e);}return resp;}
此时,redis缓存添加完毕,可以进行测试了!!!

步骤3(Quartz Schedule)

想从xml文档中定义了许多已知的许多城市名和城市ID,利用定时获取,每隔半天获取一次这些城市天气json存入缓存中,这样比上一个缓存更高效,之后还要将数据返回到微信中,所以缓存就显得尤为重要,提高了取数据的时间,使客户体验比较好。

1.获取xml,我这里只是为了演示,只用了极少数城市,根据xml格式构建相应的pojo。

<?xml version="1.0" encoding="UTF-8"?>
<c c1="0"><d d1="101280101" d2="咸阳" d3="guangzhou" d4="陕西"/><d d1="101280102" d2="兴平" d3="panyu" d4="陕西"/><d d1="101280103" d2="礼泉" d3="conghua" d4="陕西"/><d d1="101280104" d2="西安" d3="zengcheng" d4="陕西"/><d d1="101280105" d2="户县" d3="huadu" d4="陕西"/><d d1="101280201" d2="乾县" d3="shaoguan" d4="陕西"/><d d1="101280202" d2="宝鸡" d3="ruyuan" d4="陕西"/><d d1="101280203" d2="渭南" d3="shixing" d4="陕西"/><d d1="101280204" d2="大荔" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="凤翔" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="岐山" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="榆林" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="汉中" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="延安" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="铜川" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="安康" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="商洛" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="杨凌" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="神木" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="潼关" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="蒲城" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="韩城" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="柞水" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="富平" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="华阴" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="长武" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="旬邑" d3="wengyuan" d4="陕西"/><d d1="101280204" d2="泾阳" d3="wengyuan" d4="陕西"/>
</c>

2.定义Quartz的配置类

public class QuartzConfigration {private static final int TIME = 1800; //更新频率//JobDetail   定义一个job@Beanpublic JobDetail weatherDataSyncJobJobDetail(){return JobBuilder.newJob(WeatherDataSyncJob.class).withIdentity("weatherDataSynvJob").storeDurably().build();}//Trigger   触发机制, 何时去触发这个job@Beanpublic Trigger weatherDataSuncTrigger(){SimpleScheduleBuilder ScheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(TIME).repeatForever();return TriggerBuilder.newTrigger().forJob(weatherDataSyncJobJobDetail()).withIdentity("weatherDataSuncTrigger").withSchedule(ScheduleBuilder).build();}}

3.定义一个真正的job去获取xml中的城市名称

public class WeatherDataSyncJob extends QuartzJobBean {private static final Logger LOGGER = LoggerFactory.getLogger(WeatherDataServiceImpl.class);@Autowiredprivate CityDataService cityDataService;@Autowiredprivate WeatherDataService weatherDataService;@Overrideprotected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {LOGGER.info("Weather Data Sync Job");List<City> cityList = null;try {cityList = cityDataService.listCity();}catch (Exception e){LOGGER.info("Exception! " + e);}for (City city : cityList) {String cityId = city.getCityName();LOGGER.info("Weather Date Sync Job,cityId:" + cityId);weatherDataService.syncDateByCityId(cityId);}LOGGER.info("Weather Date Sync Job,End!");}
}

4.构建xmlBuilder来将xml转为指定pojo,需要用到一个工具JAXBContext来帮助我们转换。

public class XmlBuilder {public static Object xmlStrToObject(Class<?> clazz,String xmlStr) throws Exception{Object xmlObject = null;Reader reader = null;JAXBContext context = JAXBContext.newInstance(clazz);//xml转为对象Unmarshaller unmarshaller = context.createUnmarshaller();reader = new StringReader(xmlStr);xmlObject = unmarshaller.unmarshal(reader);if (null != reader){reader.close();}return xmlObject;}
}

5.创建定时获取对应的service层

@Service
public class CityDataServiceImpl implements CityDataService {@Overridepublic List<City> listCity() throws Exception {//读取内容Resource resource = new ClassPathResource("citylist.xml");BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream(),"utf-8"));StringBuffer buffer = new StringBuffer();String line = "";while ((line = br.readLine()) != null){buffer.append(line);}br.close();//xml转为Java对象CityList cityList = (CityList) XmlBuilder.xmlStrToObject(CityList.class,buffer.toString());return cityList.getCityList();}
}
至此后台编程完成,xml中的信息也存入了Redis中


当我访问一次关于榆林的天气时,控制台显示redis中有这个数据。

-------------------------------------------------后台端1.0开发正式结束!!!---------------------------------------------------

前端

工具(微信开发者工具-32位) ***这里有个坑,微信开发者工具64位那个版本下载好了根本无法打开我重新安装了好几次都不行,上网搜了之后才知道这是个坑,最简单的办法就是下载32位那个版本就行了!!!

步骤

1.先去微信公众平台去注册,选择开发小程序,填写相关的资料之后,因为我们不涉及微信支付那方面,所以不需要交三四百块钱的那个支付功能的费用。------注意要记好自己的AppID,这个一会开发时会用到。

2.打开微信开发者工具,输入信息名称目录自定义,AppID填写务必要正确,后端服务选择不使用云服务,语言看你自己选择。

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200219154059183.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L05JTklZVUFOSjEyMw==,size_16,color_FFFFFF,t_70

3.编写前端代码,我是在pages-index包下面去编写内容的,大家也可以在别的包下面编写。因为微信小程序开发使用的语言是独有的,wxml和wxss和js,其实和web前端使用的html和css和js其实同样的效果,只不过语法有差异而已。(大家可以参考微信小程序开发文档去了解)

4.先将返回前端的json格式写入index.json中,告诉前端数据的格式是什么。

{"data": {"yesterday": {"date": "","high": "","fx": "","low": "","fl": "","type": ""},"city": "","forecast": [{"date": "","high": "","fengli": "","low": "","fengxiang": "","type": ""},{"date": "","high": "","fengli": "","low": "","fengxiang": "","type": ""},{"date": "","high": "","fengli": "","low": "","fengxiang": "","type": ""},{"date": "","high": "","fengli": "","low": "","fengxiang": "","type": ""},{"date": "","high": "","fengli": "","low": "","fengxiang": "","type": ""}],"ganmao": "","wendu": ""},"status": 1000,"desc": ""
}

5.跟HTML一样搭建好页面主体框架WXML。

<view class="body"><!-- 标题 --><view class="title">小袁天气</view><!-- 搜索框view --><view class="search_con"><!-- 表单 --><form bindsubmit="formSubmit"><!-- 记得设置name值,这样JS才能接收name=keyword的值 --><input type="text" name="keyword" class="search_input" placeholder='请输入城市名?'/><button formType="submit" class="search_btn">搜索</button>    </form></view><view class="error" wx:if="{{re.status < 1}}">输入有误,请重新输入</view><!-- 搜索结果展示 --><view class="mingri" wx:if="{{re.status > 1}}"><view class="resname"><text>{{re.data.city}}</text></view><view class="resname"><text>{{re.data.yesterday.date}}</text></view><view class="resname"><text>{{re.data.yesterday.high}} {{re.yesterday.low}} {{re.yesterday.type}}</text></view><view class="resname"><text>{{re.data.ganmao}}</text></view></view><text>\n\n</text><view class='list-li mflex'  wx:if="{{re.status > 1}}" wx:for="{{re.data.forecast}}"  wx:key="re" ><view class="houxu"><view class="resname"><text>{{item.date}}</text></view>     <view  class='list-tit'><text>{{item.high}} {{item.low}}</text></view>    <view class='list-con'><text>{{item.fengxiang}}</text></view> </view><text>\n</text></view>
</view>

6.跟CSS一样设计好页面渲染WXSS


.body{background-attachment: fixed;background-image: url(http://mpic.tiankong.com/308/b0f/308b0f5807b214ec2b2d10cce6ebb738/640.jpg);height: 750px;
}
/* 搜索样式 */
.title{text-align: center;font-size: 20px;font-family: "微软雅黑";font-weight: bold;
}.error{text-align: center;color: red;}
.search_con{width: 80%;margin:20px auto;
}.search_con .search_input{border: 1px solid rgb(214, 211, 211);height: 45px;border-radius: 100px;font-size: 17px;padding-left: 15px;/*此处要用padding-left才可以把光标往右移动15像素,不可以用text-indent*/color: #333;
}.search_con .search_btn{margin-top: 15px;width: 100%;height: 45px;background: #56b273;color: #fff;border-radius: 100px;
}.empty{text-align: center;color: #f00;font-size: 15px;
}.noresult{text-align: center;color: #666;font-size: 15px;
}.search_result .resname{text-align: left;color: #333;font-size: 15px;
}

7.最关键的就是构建js,取到后台数据并且将数据存入数组中供WXML使用。

const app = getApp()
Page({data: {},//执行点击事件formSubmit: function (e) {//声明当天执行的var that = this;//获取表单所有name=keyword的值var formData = e.detail.value.keyword;//显示搜索中的提示wx.showLoading({title: '搜索中',icon: 'loading'})//向搜索后端服务器发起请求wx.request({//URLurl: 'http://localhost:8088/weather/cityName/' + formData,//发送的数据data: formData,//请求的数据时JSON格式header: {'Content-Type': 'application/json'},//请求成功success: function (res) {//控制台打印(开发调试用)console.log(res.data)//把所有结果存进一个名为re的数组that.setData({re: res.data,})//搜索成功后,隐藏搜索中的提示wx.hideLoading();}})},
})

8.注意要关闭选项<不校验合法域名>选项,点击导航栏右侧详情,选择本地设置,选择不校验合法域名。否则微信不会访问你后台的接口。

前端编写完成,测试一下可否取到数据,时间是否够快。



后续上传代码和审核遵照微信公众平台步骤即可。不过我不打算上传,现在功能太简单了,等以后功能更完整页面更漂亮再上传代码。这次写项目太艰难了,老家网太卡了,动不动就断网了,好想回学校,我太难了!!!

至此-------------天气预报1.0版本结束。

微信小程序-天气预报1.0版本相关推荐

  1. 微信小程序升级Vant Weapp版本

    微信小程序升级Vant Weapp版本 大家好,今天我们来学习一下微信小程序如何升级Vant Weapp版本,好好看,好好学,超详细的 第一步 首先你要有一个构建npm的项目 还不知道构建npm的小伙 ...

  2. 微信小程序开发手册离线版本-下载

    微信小程序 微信官方日前发布了关于小程序的帮助手册,起地址为: https://mp.weixin.qq.com/debug/wxadoc/dev/ 如果需要最新离线版,可以打开 https://we ...

  3. uniapp 微信小程序开发 解决旧版本缓存

    1.uniapp 微信小程序如何解决旧版本缓存问题 在小程序发布新版本后,小程序端是异步更新,新版本覆盖较慢.如果用户之前已经打开过小程序,通过 热启动 再进入小程序时,可能访问的还是旧版本,需要一段 ...

  4. 微信小程序名片3:0大战纸质名片,你应该知道如何选择了吧

    一大早,朋友圈和微博就被"阿根廷"和"梅西"这两个词刷屏了,小编我是个伪球迷,不敢妄下评论,但我还是心疼梅西,想起一个梗"我是梅西现在慌得一比&quo ...

  5. 微信小程序—天气预报查询

    前不久用安卓做了个天气预报,麻烦的要死,故想体验一下微信小程序开发(其实没有可比性) 发现了一个免费的天气接口 天气接口api 地址:http://wthrcdn.etouch.cn/weather_ ...

  6. 微信小程序2.9.0基础库canvas2D新API,生成海报保存到手机功能实现,包括文字换行,圆形图片,图片高度自适应等功能封装

    WxCanvas 利用canvas微信小程序原生实现的一个绘制微信小程序海报的类,基础库版本>2.9.0. 下面链接中使用的api已被废弃,所以有了本文. 微信小程序生成海报保存到手机 先看效果 ...

  7. 微信小程序开发工具最新版本已更新下载(1.02.1804120)

    下载地址: windows 64 . windows 32 . mac 本次更新修复信息如下: 1.修复 1.02.1804080 引入的编译条件为分包内页面时无法加载的问题 1. 更新到最新版本后 ...

  8. 更改微信小程序的基础版本库;更改uni-app小程序基础库;更改用户的微信小程序基础库最低版本;设置用户的微信小程序版本库;

    需求场景:微信小程序不少API都有最低版本支持,为了避免不必要的麻烦,我们可以根据需要给小程序设置基础库最低版本,这样若用户使用的基础库版本低于设置的最低版本要求,则无法正常使用小程序,并提示更新微信 ...

  9. 微信小程序 table表格 PC版本

    公司项目啊....其实小程序页面的商品列表也有宫格.列表.大图模式了,尽管描述得不那么详细,但是信息量也能看到个大概,但是领导或业务员比较喜欢看表格详细点,罗列得比较清晰. 所以要求可以通过小程序分享 ...

最新文章

  1. 下面方框中,那些包括有220欧姆的电阻呢?
  2. mysql的字段空格是null_MySQL中NULL与空字符串 空格问题
  3. redis抽奖并发_Redis优化高并发下的秒杀性能
  4. 【读书笔记】阅读的危险
  5. C++小项目-吃豆子游戏
  6. Dataset、IterableDataset 读取大数据的思路
  7. JavaScript-jQuery操作Dom元素
  8. python解决最优化问题_python实现最优化算法
  9. 宝塔linux修改默认编码,宝塔linux面板防护CC设置(示例代码)
  10. ubuntu学习日记--Lesson6:shell,bash,dash
  11. 英语总结系列(九):百忙中依然坚持的九月
  12. ODA(Open Design Alliance)介绍
  13. WordPress伪原创工具-更新网站一键伪原创发布软件
  14. 东芝Toshiba e-STUDIO245 一体机驱动
  15. C语言sqrt求平方根函数注意点
  16. 360 极速模式 html,360浏览器极速模式怎么开
  17. 简单计算机硬件知识ppt,计算机硬件知识教程课件.ppt
  18. 学习ARM开发(15)
  19. MIME类型(content-type)一览
  20. Go语言如何实现删除Winmail邮箱系统中收件箱的所有邮件

热门文章

  1. 数据包从物理网卡流经 Open vSwitch 进入 OpenStack 云主机的流程
  2. CHAPTER 2 目录及文件
  3. vuex入门到实战——实现一个todoList待办清单【学习记录】
  4. Windows中快速获取文件目录的方法
  5. Gaussdb 存储过程
  6. 软件测试/测试开发丨必知必会的Docker 命令
  7. 写博客文档的神器:Typora 、Mathpix Snipping Tool
  8. 软件企业认定条件政策
  9. 《图解密码技术》读后的总结
  10. 【UE Unreal Camera】【保姆级教程二】手把手教你通过UE获取摄像头帧数据