java 定时获取城市气象信息

免费的气象信息获取会有次数的限制,所以存在需要后台去获取到气象信息进行存储,然后定时去更新气象信息来避免因为次数限制而导致程序的不可用。经过一番百度,

终于找到了可以使用的数据。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。希望大佬可以留下宝贵的指导意见!

猜你喜欢

转载自blog.csdn.net/duan196_118/article/details/110671220