获取天气信息
需求
页面需要显示天气信息,所以需要调用天气API获取天气信息,找了好多api,还是SOJSON的最方便最实惠(免费
),不需要注册和申请秘钥。
源代码
- 直接贴代码,拿着即用(为了减少访问接口压力,这里使用了redis缓存4小时)
/**
* 获取天气信息
* @param cityId 城市id 101030100
* @return
*/
public WeatherInfoVo getWeatherInfo(String cityId) {
if(redisCache.hasKey(getWeatherKey(cityId))){
WeatherInfoDto weatherInfoDto = redisCache.getCacheObject(getWeatherKey(cityId));
return weatherInfoDtoToVo(weatherInfoDto);
}
WeatherInfoDto weatherInfoDto = new WeatherInfoDto();
try {
HttpRequest get = HttpUtil.createGet(BaseBoConstants.WEATHER_URL + cityId);
HttpResponse response = get.execute();
if (response.isOk()) {
log.warn("获取天气信息失败,失败原因:{}", response.body());
}
JSONObject jsonObject = JSONUtil.parseObj(response.body());
String data = jsonObject.getStr("data");
if (data == null) {
log.warn("获取天气信息失败,失败原因:{}", response.body());
}
JSONArray forecastArray = JSONUtil.parseObj(data).getJSONArray("forecast");
if (forecastArray == null) {
log.warn("获取天气信息失败,失败原因:{}", response.body());
}
List<WeatherInfoDto> weatherInfoDtoList = JSONUtil.toList(forecastArray, WeatherInfoDto.class);
// 获取今日天气
weatherInfoDto = weatherInfoDtoList != null && !weatherInfoDtoList.isEmpty() ? weatherInfoDtoList.get(0) : initWeatherInfoDto();
weatherInfoDto.setIcon(WeatherIconEnum.getIconByType(weatherInfoDto.getType()));
}catch (Exception e){
log.error("获取天气信息失败...");
}
redisCache.setCacheObject(getWeatherKey(BaseBoConstants.WEATHER_CITY_CODE), weatherInfoDto, 4, TimeUnit.HOURS);
return weatherInfoDtoToVo(weatherInfoDto);
}
/**
* 获取天气redis key
* @param cityId
* @return
*/
private String getWeatherKey(String cityId){
return CacheConstants.WEATHER + cityId;
}
/**
* 天气dto转为vo给页面显示
* @param dto
* @return
*/
private WeatherInfoVo weatherInfoDtoToVo(WeatherInfoDto dto){
return WeatherInfoVo.builder()
.type(dto.getType())
.lowHigh(regexTemp(dto.getLow()) + BaseBoConstants.WEATHER_CONNECTOR + regexTemp(dto.getHigh()))
.icon(dto.getIcon())
.date(dto.getYmd())
.build();
}
/**
* 使用正则表达式捕获取温度用
* @param tempStr 高温 25.0℃
* @return
*/
private String regexTemp(String tempStr){
String regex = "(\\d+℃)";
// 创建Pattern对象
Pattern pattern = Pattern.compile(regex);
// 创建Matcher对象
Matcher matcher = pattern.matcher(tempStr);
// 查找匹配
if (matcher.find()) {
return matcher.group(1);
} else {
log.error("没有找到匹配的温度值");
}
return "";
}
/**
* 当查询不到天气信息时给于默认天气
* @return
*/
private WeatherInfoDto initWeatherInfoDto(){
DateTime now = DateUtil.date();
String type = "晴";
return WeatherInfoDto.builder().date(DateUtil.dayOfMonth(now) + "")
.high("高温 25.0℃")
.low("低温 15.0℃")
.ymd(DateUtil.format(now, "yyyy-MM-dd"))
.week("星期" + NumberChineseFormatter.format(DateUtil.weekOfMonth(now), false, false))
.sunrise("05:56")
.sunset("18:12")
.aqi(108.0)
.fx("西北风")
.fl("4-5级")
.type(type)
.icon(WeatherIconEnum.getIconByType(type))
.notice("愿你拥有比阳光明媚的心情").build();
}
public enum WeatherIconEnum {
/**
* 天气类型和图标枚举信息
*/
SUNNY("晴", "☀️"),
MOSTLY_CLOUDY("多云", "⛅️"),
OVERCAST("阴", "☁️"),
SHOWERS("阵雨", "\uD83C\uDF26️"),
THUNDERSTORMS("雷阵雨", "⛈️"),
LIGHT_RAIN("小雨", "\uD83C\uDF27️"),
MODERATE_RAIN("中雨", "\uD83C\uDF27️"),
HEAVY_RAIN("大雨", "\uD83C\uDF27️"),
TORRENTIAL_RAIN("暴雨", "\uD83C\uDF27️"),
SNOW("雪", "❄️"),
SLEET("雨夹雪", "\uD83C\uDF28️"),
FOG("雾", "\uD83C\uDF2B️"),
FROST("霜", "❄️"),
HAIL("冰雹", "\uD83C\uDF28️"),
WINDY("风", "\uD83C\uDF2C️"),
DEFAULT("未知", "☀️"),
;
private String type;
private String icon;
WeatherIconEnum(String type, String icon) {
this.type = type;
this.icon = icon;
}
public static String getIconByType(String type){
if(StringUtils.isNotEmpty(type)){
for (WeatherIconEnum value : WeatherIconEnum.values()) {
if(StringUtils.equals(value.type, type)){
return value.icon;
}
}
}
return DEFAULT.icon;
}
}
返回信息详解
- 摘自SOJSON文档
{
"time": "2018-09-22 12:37:21",//系统更新时间
"cityInfo": {
"city": "天津市", //请求城市
"cityId": "101030100",//请求ID
"parent": "天津", //上级,一般是省份
"updateTime": "12:32"//天气更新时间
},
"date": "20180922", //当前天气的当天日期
"message": "Success !", //返回message
"status": 200, //返回状态
"data": {
"shidu": "22%", //湿度
"pm25": 15.0, //pm2.5
"pm10": 46.0, //pm10
"quality": "优", //空气质量
"wendu": "24", //温度
"ganmao": "各类人群可自由活动",//感冒提醒(指数)
"yesterday": { //昨天天气
"date": "21", //日 去掉了原来的 日字 + 星期,如 21日星期五 变成了21,星期和年月日在下面
"ymd": "2018-09-21", //年月日 (新增)
"week": "星期五", //星期 (新增)
"sunrise": "05:56", //日出
"high": "高温 25.0℃", //当天最高温
"low": "低温 15.0℃", //当天最低温
"sunset": "18:12", //日落
"aqi": 108.0, //空气指数
"fx": "西北风", //风向
"fl": "4-5级", //风力
"type": "晴", //天气
"notice": "愿你拥有比阳光明媚的心情"//天气描述
},
"forecast": [//今天+未来4天
{
"date": "22",
"ymd": "2018-09-22", //年月日 (新增)
"week": "星期六", //星期 (新增)
"sunrise": "05:57",
"high": "高温 26.0℃",
"low": "低温 15.0℃",
"sunset": "18:10",
"aqi": 55.0,
"fx": "西北风",
"fl": "4-5级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "23",
"ymd": "2018-09-22", //年月日 (新增)
"week": "星期日", //星期 (新增)
"sunrise": "05:58",
"high": "高温 23.0℃",
"low": "低温 14.0℃",
"sunset": "18:09",
"aqi": 29.0,
"fx": "西北风",
"fl": "4-5级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "24",
"ymd": "2018-09-22", //年月日 (新增)
"week": "星期一", //星期 (新增)
"sunrise": "05:59",
"high": "高温 24.0℃",
"low": "低温 15.0℃",
"sunset": "18:07",
"aqi": 25.0,
"fx": "西北风",
"fl": "<3级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "25",
"ymd": "2018-09-22", //年月日 (新增)
"week": "星期二", //星期 (新增)
"sunrise": "06:00",
"high": "高温 24.0℃",
"low": "低温 16.0℃",
"sunset": "18:05",
"aqi": 56.0,
"fx": "西南风",
"fl": "<3级",
"type": "晴",
"notice": "愿你拥有比阳光明媚的心情"
},
{
"date": "26",
"ymd": "2018-09-22", //年月日 (新增)
"week": "星期三", //星期 (新增)
"sunrise": "06:01",
"high": "高温 24.0℃",
"low": "低温 17.0℃",
"sunset": "18:04",
"aqi": 86.0,
"fx": "西南风",
"fl": "3-4级",
"type": "阴",
"notice": "不要被阴云遮挡住好心情"
}
]
}
}
天气预报API城市代号
- 文件内容多,用文件上传上去了,文件链接:天气预报API城市代号