免费的气象信息获取会有次数的限制,所以存在需要后台去获取到气象信息进行存储,然后定时去更新气象信息来避免因为次数限制而导致程序的不可用。经过一番百度,
终于找到了可以使用的数据。http://api.k780.com/?app=weather.today&weaid=1&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
可以参考文章:https://www.cnblogs.com/yunjuanyunshu/p/9234037.html
下面就写一个定时任务去拉取气象信息,准备工作还需要我们去获取全国城市代码
/**
* 定时拉取城市气象信息
*/
public void runTask(){
Weather weather = new Weather();
List<Weather> weathers = weatherMapper.selectWeatherList(weather);
try {
//api url地址
//String url ="http://api.k780.com/?app=weather.today&weaid=1&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";
String url = "http://api.k780.com/";
//post请求
HttpMethod method =HttpMethod.POST;
// 封装参数,千万不要替换为Map与HashMap,否则参数无法传递
MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
params.add("app"," weather.today");
params.add("appkey","55901");
params.add("sign","73b4e2e2d5c90f311a2a749c095aa6e0");
Date date = new Date();
params.add("format","json");
int count = 0;
for (Weather entity : weathers) {
params.add("weaid",entity.getCityName());
String client = RestTemplateUtil.client(url, method, params);
JSONObject jsonObject = JSONObject.parseObject(client);
String success = jsonObject.getString("success");
if (!"1".equals(success)){
log.info("获取气象信息失败:{}",entity.getCityName());
continue;
}
String resultJson = jsonObject.getString("result");
entity.setUpdateTime(date);
entity.setWeatherData(resultJson);
log.info("获取{}信息:{}",entity.getCityName(),entity.getWeatherData());
weatherMapper.updateByPrimaryKeySelective(entity);
count++;
}
log.info("成功获取数量:{}",count);
}catch (HttpClientErrorException e){
log.info("http客户端请求出错了!");
}
}
/**
* 获取城市列表
*/
public void runTaskOne(){
try {
//api url地址
String url = "http://api.k780.com:88/";
String cityUrl = "http://api.k780.com/?app=weather.city&cou=1&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";
//post请求
HttpMethod method =HttpMethod.POST;
// 封装参数,千万不要替换为Map与HashMap,否则参数无法传递
MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
params.add("app"," weather.city");
params.add("cou","1");
params.add("appkey","10003");
params.add("sign","b59bc3ef6191eb9f747dd4e83c99f2a4");
params.add("format","json");
//发送http请求并返回结果
String client = RestTemplateUtil.client(cityUrl, method, params);
JSONObject jsonObject = JSONObject.parseObject(client);
String result = jsonObject.getString("success");
if (!"1".equals(result)){
return;
}
System.out.println(jsonObject);
JSONObject datas = jsonObject.getJSONObject("result").getJSONObject("datas");
List<Weather> weathers = new ArrayList<>(2972);
Date date = new Date();
// 2972
for (int i = 1; i <= 2972; i++) {
String jsonstr= datas.getString(i + "");
if (!StringUtils.isBlank(jsonstr)){
Weather weather = JSONObject.parseObject(jsonstr, Weather.class);
if (!StringUtils.isBlank(weather.getCityId())){
weather.setUpdateTime(date);
weathers.add(weather);
}
}
}
System.out.println("获取城市数量:"+weathers.size());
weatherMapper.insertBatchWeather(weathers);
}catch (HttpClientErrorException e){
System.out.println("http客户端请求出错了!");
}
}
使用到的工具类
mport org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateUtil {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory){
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//单位为ms
factory.setConnectTimeout(5000);//单位为ms
return factory;
}
private static RestTemplate restTemplate;
@Autowired
private void setRestTemplate(RestTemplate restTemplate){
this.restTemplate=restTemplate;
}
/**
* post 请求
* @param url
* @param method
* @param params
* @return
*/
public static String client(String url, HttpMethod method, MultiValueMap<String, String> params){
HttpHeaders headers = new HttpHeaders();
// 请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
// 执行HTTP请求
ResponseEntity<String> response = restTemplate.exchange(url, method, requestEntity, String.class);
return response.getBody();
}
}
在测试时,是直接存储到数据库中了,先存储城市的id,然后把获取到城市的气象信息存储到对应的字段中,大家可以根据自己项目的情况去进行存储。记录下在测试中踩到的坑。。
根据上面的介绍,我们可以看出在拉取气象信息时,需要传入对应的参数,而MultiValueMap可以巧妙的解决字符串拼接问题,但是在使用RestTemplate发送get请求时,用postMan可以请求到数据,但是在程序中却无法请求成功,这是RestTemplate发起get请求时的一个坑,导致参数无法获取。在使用RestTemplate进行发送请求时,注意它会根据不同的请求头走不同的逻辑,这个在后期的应用中还要多多总结,可以参考博客:https://www.cnblogs.com/myf008/p/8893729.html。希望大佬可以留下宝贵的指导意见!