JsonService.java 9.49 KB
package com.viontech.service.impl;


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.rholder.retry.*;
import com.google.common.base.Predicates;
import com.viontech.model.*;
import com.viontech.utils.HttpUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * @author zhaibolin
 */
//@Configuration
@Service
public class JsonService {

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    @Autowired
    private Json jsonclass;

    public SimpleWeather getWeatherInfo(int cityId) {
        System.out.println("城市[" + cityId + "]获取天气信息");

        Map<String, WeatherMessage> dataMap = new HashMap<>();

        // 调用weather接口
        Callable<Boolean> weatherCallable = () -> {
            String json = "";
            try {
                String host = jsonclass.getHost1();
                String path = jsonclass.getPath1();
                String method = "POST";
                String appcode = jsonclass.getAppcode();
                Map<String, String> headers = new HashMap<>();
                headers.put("Authorization", "APPCODE " + appcode);
                headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                Map<String, String> querys = new HashMap<>();
                Map<String, String> bodys = new HashMap<>();
                bodys.put("cityId", String.valueOf(cityId));
                HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
                json = EntityUtils.toString(response.getEntity());

                ObjectMapper mapper = new ObjectMapper();
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
                WeatherMessage weatherMessage = mapper.readValue(json, WeatherMessage.class);
                if (null != weatherMessage) {
                    dataMap.put("WEATHER", weatherMessage);
                    return true;
                }
            } catch (Exception e) {
                // 接口调用发生异常时,打印接口返回信息
                System.out.println("调用weather接口发生异常,接口返回数据:" + json);
                throw e;
            }
            return false;
        };
        Retryer<Boolean> weatherRetryer = RetryerBuilder.<Boolean>newBuilder()
                // 发生异常时重试
                .retryIfException()
                // 返回false时重试
                .retryIfResult(Predicates.equalTo(false))
                // 每次重试等待时间
                .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS))
                // 最大重试次数
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                // 记录第几次执行
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        System.out.println("[weather retry]times=" + attempt.getAttemptNumber());
                    }
                })
                .build();

        try {
            weatherRetryer.call(weatherCallable);
        } catch (Exception e) {
            System.out.println("城市[" + cityId + "]调用Weather接口失败");
            return null;
        }

        // 调用aqi接口
        Callable<Boolean> aqiCallable = () -> {
            String json = "";
            try {
                String host = jsonclass.getHost2();
                String path = jsonclass.getPath2();
                String method = "POST";
                String appcode = jsonclass.getAppcode();
                Map<String, String> headers = new HashMap<>();
                headers.put("Authorization", "APPCODE " + appcode);
                headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                Map<String, String> querys = new HashMap<>();
                Map<String, String> bodys = new HashMap<>();
                bodys.put("cityId", String.valueOf(cityId));
                HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
                json = EntityUtils.toString(response.getEntity());

                ObjectMapper mapper = new ObjectMapper();
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
                WeatherMessage aqiMessage = mapper.readValue(json, WeatherMessage.class);
                if (null != aqiMessage) {
                    dataMap.put("AQI", aqiMessage);
                    return true;
                }
            } catch (Exception e) {
                // 接口调用发生异常时,打印接口返回信息
                System.out.println("调用AQI接口发生异常,接口返回数据:" + json);
                throw e;
            }
            return false;
        };
        Retryer<Boolean> aqiRetryer = RetryerBuilder.<Boolean>newBuilder()
                // 发生异常时重试
                .retryIfException()
                // 返回false时重试
                .retryIfResult(Predicates.equalTo(false))
                // 每次重试等待时间
                .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS))
                // 最大重试次数
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                // 记录第几次执行
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        System.out.println("[aqi retry]times=" + attempt.getAttemptNumber());
                    }
                })
                .build();

        try {
            aqiRetryer.call(aqiCallable);
        } catch (Exception e) {
            System.out.println("城市[" + cityId + "]调用AQI接口失败");
            return null;
        }

        return weathers2SimpleWeather(dataMap.get("WEATHER"), dataMap.get("AQI"));
    }

    private SimpleWeather weathers2SimpleWeather(WeatherMessage weatherMessage, WeatherMessage weatherMessage2) {
        Data data = weatherMessage.getData();
        if (data == null) {
            return null;
        }
        data.getCity();
        data.getForecast();

        City city = data.getCity();
        if (city == null) {
            return null;
        }
        Forecast forecast = data.getForecast().get(0);
        if (forecast == null) {
            return null;
        }

        SimpleWeather simpleWeather = new SimpleWeather();
        simpleWeather.setType(getWeatherCode(forecast.getConditionDay()));
        simpleWeather.setData_date(forecast.getPredictDate());
        simpleWeather.setHtemp(forecast.getTempDay());
        simpleWeather.setLtemp(forecast.getTempNight());
        if (weatherMessage2.getData().getAqi() == null) {
            simpleWeather.setAqi("0");
        } else {
            simpleWeather.setAqi(weatherMessage2.getData().getAqi().getValue());
        }
        simpleWeather.setFengli(forecast.getWindLevelDay());
        simpleWeather.setFengxiang(forecast.getWindDirDay());

        return simpleWeather;
    }

    private int getWeatherCode(String weather) {
        switch (weather) {
            case "晴":
            case "大部晴朗":
                return 1;
            case "多云":
            case "少云":
                return 2;
            case "阴":
                return 3;
            case "阵雨":
            case "局部阵雨":
            case "小阵雨":
            case "强阵雨":
                return 4;
            case "雷阵雨":
            case "雷电":
            case "雷暴":
                return 5;
            case "雷阵雨伴有冰雹":
            case "冰雹":
            case "冰粒":
            case "冰针":
                return 6;
            case "雨夹雪":
                return 7;
            case "小雨":
            case "小到中雨":
                return 8;
            case "中雨":
            case "雨":
                return 9;
            case "大雨":
            case "中到大雨":
                return 10;
            case "暴雨":
            case "大暴雨":
            case "特大暴雨":
            case "大到暴雨":
                return 11;
            case "阵雪":
            case "小阵雪":
                return 12;
            case "小雪":
                return 13;
            case "中雪":
            case "小到中雪":
            case "雪":
                return 14;
            case "大雪":
                return 15;
            case "暴雪":
                return 16;
            case "雾":
            case "冻雾":
                return 17;
            case "冻雨":
                return 18;
            case "霾":
            case "沙尘暴":
            case "强沙尘暴":
                return 19;
            case "浮尘":
            case "尘卷风":
            case "扬沙":
                return 20;
            default:
                return -1;
        }
    }

}