1.将从接口拿到的json转为pojo。
2.使用Redis缓存提升应用的并发访问能力。
3.Quartz Schedule定时获取天气数据存入缓存进一步提升并发访问能力。
拿到数据传到小程序界面(直男的审美做出来的界面实在太丑了,1.0版本就先这样吧)
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
{
"data": {
"yesterday": {
"date": "18日星期二",
"high": "高温 6℃",
"fx": "南风",
"low": "低温 -7℃",
"fl": "",
"type": "多云"
},
"city": "榆林",
"forecast": [
{
"date": "19日星期三",
"high": "高温 7℃",
"fengli": "",
"low": "低温 -6℃",
"fengxiang": "东南风",
"type": "晴"
},
{
"date": "20日星期四",
"high": "高温 4℃",
"fengli": "",
"low": "低温 -7℃",
"fengxiang": "西北风",
"type": "多云"
},
{
"date": "21日星期五",
"high": "高温 2℃",
"fengli": "",
"low": "低温 -9℃",
"fengxiang": "西北风",
"type": "多云"
},
{
"date": "22日星期六",
"high": "高温 6℃",
"fengli": "",
"low": "低温 -2℃",
"fengxiang": "东南风",
"type": "晴"
},
{
"date": "23日星期天",
"high": "高温 11℃",
"fengli": "",
"low": "低温 -2℃",
"fengxiang": "东南风",
"type": "晴"
}
],
"ganmao": "天气寒冷,且昼夜温差很大,极易发生感冒。请特别注意增加衣服保暖防寒。",
"wendu": "3"
},
"status": 1000,
"desc": "OK"
}
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;
}
@Configuration
public class RestConfiguration {
@Autowired
private RestTemplateBuilder builder;
@Bean
public RestTemplate restTemplate(){
return builder.build();
}
}
这时就可以先进行一下测试了,如果可以访问到数据的话再进行下一步缓存的实现。
<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有成功导入。这个问题等回到家网络好了再研究。
<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>
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.timeout=120000
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;
}
想从xml文档中定义了许多已知的许多城市名和城市ID,利用定时获取,每隔半天获取一次这些城市天气json存入缓存中,这样比上一个缓存更高效,之后还要将数据返回到微信中,所以缓存就显得尤为重要,提高了取数据的时间,使客户体验比较好。
<?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>
public class QuartzConfigration {
private static final int TIME = 1800; //更新频率
//JobDetail 定义一个job
@Bean
public JobDetail weatherDataSyncJobJobDetail(){
return JobBuilder.newJob(WeatherDataSyncJob.class).withIdentity("weatherDataSynvJob")
.storeDurably().build();
}
//Trigger 触发机制, 何时去触发这个job
@Bean
public Trigger weatherDataSuncTrigger(){
SimpleScheduleBuilder ScheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(TIME).repeatForever();
return TriggerBuilder.newTrigger().forJob(weatherDataSyncJobJobDetail())
.withIdentity("weatherDataSuncTrigger").withSchedule(ScheduleBuilder).build();
}
}
public class WeatherDataSyncJob extends QuartzJobBean {
private static final Logger LOGGER = LoggerFactory.getLogger(WeatherDataServiceImpl.class);
@Autowired
private CityDataService cityDataService;
@Autowired
private WeatherDataService weatherDataService;
@Override
protected 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!");
}
}
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;
}
}
@Service
public class CityDataServiceImpl implements CityDataService {
@Override
public 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();
}
}
当我访问一次关于榆林的天气时,控制台显示redis中有这个数据。
工具(微信开发者工具-32位) ***这里有个坑,微信开发者工具64位那个版本下载好了根本无法打开我重新安装了好几次都不行,上网搜了之后才知道这是个坑,最简单的办法就是下载32位那个版本就行了!!!
;
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;
}
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({
//URL
url: '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();
}
})
},
})
后续上传代码和审核遵照微信公众平台步骤即可。不过我不打算上传,现在功能太简单了,等以后功能更完整页面更漂亮再上传代码。这次写项目太艰难了,老家网太卡了,动不动就断网了,好想回学校,我太难了!!!