Springboot 天气api开发

从天气项目开始

标签: springboot api


天气接口

  • 接口
http://wthrcdn.etouch.cn/weather_mini?city=滁州
http://wthrcdn.etouch.cn/weather_mini?citykey=341100
http://mobile.weather.com.cn/js/citylist.xml

接口案例

逻辑实现:实例化返回对象,通过配置httpclient进行请求发送,将返回结果通过ObjectMapper中的readValue进行反序列化。

  • 实例化对象

package com.xiaojinzi.dataobject;

import lombok.Data;

import java.io.Serializable;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description 数据返回模型
 */

@Data
public class WeatherResult implements Serializable{

    /** 数据 .*/
    private WeatherData data;

    /** 状态码 .*/
    private Integer status;

    /** 描述 .*/
    private String desc;
}


package com.xiaojinzi.dataobject;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description 天气数据
 */

@Data
public class WeatherData  implements Serializable{

    /** 昨日天气情况 .*/
    private Yesterday yesterday;

    /** 未来七日预测 .*/
    private List<Forecast> forecast;

    /** 城市 .*/
    private String city;

    /** 空气指数 .*/
    private String aqi;

    /** 提示 .*/
    private String ganmao;

    /** 温度 .*/
    private String wendu;
}


package com.xiaojinzi.dataobject;

import lombok.Data;

import java.io.Serializable;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description 昨日天气
 */
@Data
public class Yesterday implements Serializable{

    /** 日期 .*/
    private String date;

    /** 最高温度 .*/
    private String high;

    /** 风向 .*/
    private String fx;

    /** 最低温度 .*/
    private String low;

    /** 风力 .*/
    private String fl;

    /** 天气情况 .*/
    private String type;
}


package com.xiaojinzi.dataobject;

import lombok.Data;

import java.io.Serializable;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description 天气预测
 */

@Data
public class Forecast implements Serializable {

    /** 日期 .*/
    private String date;

    /** 最高温度 .*/
    private String high;

    /** 风力 .*/
    private String fengli;

    /** 最低温度 .*/
    private String low;

    /** 风向 .*/
    private String fengxiang;

    /** 天气情况 .*/
    private String type;

}


  • 反序列化

package com.xiaojinzi.services.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaojinzi.config.WeatherApiConfig;
import com.xiaojinzi.dataobject.WeatherData;
import com.xiaojinzi.dataobject.WeatherResult;
import com.xiaojinzi.services.WeatherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description
 */
@Service
public class WeatherServiceImpl implements WeatherService {

    @Autowired
    private WeatherApiConfig weatherApiConfig;

    @Autowired
    private RestTemplate restTemplate;


    public WeatherResult getWeatherDataByCityName(String cityName) {
        /** 连接配置 .*/
        String uri = weatherApiConfig.getUrl() +  "city="  + cityName;
        /** 获取返回结果 .*/
        ResponseEntity<String> result = restTemplate.getForEntity(uri,String.class);
        /** 返回对象转换 .*/
        String jsonPaser = null;
        if(result.getStatusCodeValue() == 200) {
            jsonPaser = result.getBody();
        }else {
            jsonPaser = null;
        }
        WeatherResult weatherResult = null;
        ObjectMapper objectMapper = new ObjectMapper();
        try{
            /** string转换json .*/
            weatherResult = objectMapper.readValue(jsonPaser,WeatherResult.class);
        }catch (Exception e){
            e.printStackTrace();
        }
        return weatherResult;
    }


    public WeatherResult getWeatherDataByCityId(String cityId) {
        return null;
    }
}

  • 配置RestTemplate
package com.xiaojinzi.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description RestTemplate配置
 */
@Configuration
public class RestTemplateConfig {

    @Autowired
    private RestTemplateBuilder builder;

    @Bean
    public RestTemplate restTemplate(){
        return builder.build();
    }
}

Redis提升并发访问量

windows下redis配置,下载地址

  • 配置redis启动

打开解压文件中的redis.windows.conf文件,找到 maxmemory 添加内容如下

#
# maxmemory <bytes>
maxmemory 1024000000

添加start.bat启动文件,内容如下,双击启动就行了

redis-server.exe  redis.windows.conf
  • 提高访问量,减少三方的服务器压力。通过设置一个内容键值队,并设置30分钟时长。
package com.xiaojinzi.services.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaojinzi.config.WeatherApiConfig;
import com.xiaojinzi.dataobject.WeatherData;
import com.xiaojinzi.dataobject.WeatherResult;
import com.xiaojinzi.services.WeatherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description
 */
@Service
public class WeatherServiceImpl implements WeatherService {

    @Autowired
    private WeatherApiConfig weatherApiConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    public WeatherResult getWeatherDataByCityName(String cityName) {
        /** 连接配置 .*/
        String uri = weatherApiConfig.getUrl() +  "city="  + cityName;
        String key = uri;

        /** 返回对象转换 .*/
        String jsonPaser = null;

        /** 内容数据库中获值 .*/
        ValueOperations<String, String> ops =  stringRedisTemplate.opsForValue();

        /** 判断内存数据库中是否存在 .*/
        if(stringRedisTemplate.hasKey(key)){
            jsonPaser = ops.get(key);
        }else {
            /** 存储数据入库 .*/
            /** 获取返回结果 .*/
            ResponseEntity<String> result = restTemplate.getForEntity(uri,String.class);
            if(result.getStatusCodeValue() == 200) {
                jsonPaser = result.getBody();
            }else {
                jsonPaser = null;
            }

            ops.set(key,jsonPaser,weatherApiConfig.getReTimeout(), TimeUnit.SECONDS);

        }


        WeatherResult weatherResult = null;
        ObjectMapper objectMapper = new ObjectMapper();
        try{
            /** string转换json .*/
            weatherResult = objectMapper.readValue(jsonPaser,WeatherResult.class);
        }catch (Exception e){
            e.printStackTrace();
        }
        return weatherResult;
    }


    public WeatherResult getWeatherDataByCityId(String cityId) {
        return null;
    }
}

  • 通过redis 可视化看结果

定时器quartz

通过配置定时器定时刷新获取天气,引用quartz依赖,配置定时刷新类继承QuartzJobBean类,并实例executeInternal方法。配置定时器上下文,刷新任务JobDetailBuilder,刷新方式TriggerBuilder。

  • 引用
<!--定时器依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
  • 配置刷新类

package com.xiaojinzi.job;


import com.xiaojinzi.services.WeatherService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;


/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description 天气信息定时刷新
 */
@Slf4j
public class WeatherDataSyncJob extends QuartzJobBean {
    @Autowired
    private WeatherService weatherService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        weatherService.getWeatherDataByCityName("合肥");
    }
}

  • 配置定时器上下文
package com.xiaojinzi.config;

import com.xiaojinzi.job.WeatherDataSyncJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/3
 * @description 定时器配置
 */
@Configuration
public class QuartzConfig {

    @Autowired
    private WeatherApiConfig weatherApiConfig;


    /**
     * 定时刷新任务
     * @return
     */
    @Bean
    public JobDetail weatherDataSyncJobDetail(){
        return JobBuilder.newJob(WeatherDataSyncJob.class).withIdentity("weatherDataSyncJobDetail")
                .storeDurably().build();
    }

    /**
     * 定时刷新方式
     * @return
     */
    @Bean
    public Trigger weatherDataSyncTrigger(){
        /** 设置刷新方式 .*/
        SimpleScheduleBuilder scheduleBuilder  = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(weatherApiConfig.getReTimeout()).repeatForever();
        /** 触发器 .*/
        return TriggerBuilder.newTrigger().forJob(weatherDataSyncJobDetail())
                .withIdentity("weatherDataSyncTrigger").withSchedule(scheduleBuilder).build();
    }
}

获取城市信息

通过读取xml文件的形式来获取城市,需将xml文件转换成obj对象,之后通过循环城市来进行城市天气信息的添加城市信息。

  • xml文件内容
<?xml version="1.0" encoding="UTF-8"?>
    <c c1="0">
        <d d1="101220101" d2="合肥" d3="hefei" d4="安徽"/>
        <d d1="101220102" d2="长丰" d3="changfeng" d4="安徽"/>
        <d d1="101220103" d2="肥东" d3="feidong" d4="安徽"/>
        <d d1="101220104" d2="肥西" d3="feixi" d4="安徽"/>
        <d d1="101220201" d2="蚌埠" d3="bengbu" d4="安徽"/>
        <d d1="101220202" d2="怀远" d3="huaiyuan" d4="安徽"/>
        <d d1="101220203" d2="固镇" d3="guzhen" d4="安徽"/>
        <d d1="101220204" d2="五河" d3="wuhe" d4="安徽"/>
        <d d1="101220301" d2="芜湖" d3="wuhu" d4="安徽"/>
        <d d1="101220302" d2="繁昌" d3="fanyang" d4="安徽"/>
        <d d1="101220303" d2="芜湖县" d3="wuhuxian" d4="安徽"/>
        <d d1="101220304" d2="南陵" d3="nanling" d4="安徽"/>
        <d d1="101220401" d2="淮南" d3="huainan" d4="安徽"/>
        <d d1="101220402" d2="凤台" d3="fengtai" d4="安徽"/>
        <d d1="101220403" d2="潘集" d3="panji" d4="安徽"/>
        <d d1="101220501" d2="马鞍山" d3="maanshan" d4="安徽"/>
        <d d1="101220502" d2="当涂" d3="dangtu" d4="安徽"/>
        <d d1="101220601" d2="安庆" d3="anqing" d4="安徽"/>
        <d d1="101220602" d2="枞阳" d3="zongyang" d4="安徽"/>
        <d d1="101220603" d2="太湖" d3="taihu" d4="安徽"/>
        <d d1="101220604" d2="潜山" d3="qianshan" d4="安徽"/>
        <d d1="101220605" d2="怀宁" d3="huaining" d4="安徽"/>
        <d d1="101220606" d2="宿松" d3="susong" d4="安徽"/>
        <d d1="101220607" d2="望江" d3="wangjiang" d4="安徽"/>
        <d d1="101220608" d2="岳西" d3="yuexi" d4="安徽"/>
        <d d1="101220609" d2="桐城" d3="tongcheng" d4="安徽"/>
        <d d1="101220701" d2="宿州" d3="suzhou" d4="安徽"/>
        <d d1="101220702" d2="砀山" d3="dangshan" d4="安徽"/>
        <d d1="101220703" d2="灵璧" d3="lingbi" d4="安徽"/>
        <d d1="101220704" d2="泗县" d3="sixian" d4="安徽"/>
        <d d1="101220705" d2="萧县" d3="xiaoxian" d4="安徽"/>
        <d d1="101220801" d2="阜阳" d3="fuyang" d4="安徽"/>
        <d d1="101220802" d2="阜南" d3="funan" d4="安徽"/>
        <d d1="101220803" d2="颍上" d3="yingshang" d4="安徽"/>
        <d d1="101220804" d2="临泉" d3="linquan" d4="安徽"/>
        <d d1="101220805" d2="界首" d3="jieshou" d4="安徽"/>
        <d d1="101220806" d2="太和" d3="taihe" d4="安徽"/>
        <d d1="101220901" d2="亳州" d3="bozhou" d4="安徽"/>
        <d d1="101220902" d2="涡阳" d3="guoyang" d4="安徽"/>
        <d d1="101220903" d2="利辛" d3="lixin" d4="安徽"/>
        <d d1="101220904" d2="蒙城" d3="mengcheng" d4="安徽"/>
        <d d1="101221001" d2="黄山" d3="huangshan" d4="安徽"/>
        <d d1="101221002" d2="黄山区" d3="huangshanqu" d4="安徽"/>
        <d d1="101221003" d2="屯溪" d3="tunxi" d4="安徽"/>
        <d d1="101221004" d2="祁门" d3="qimen" d4="安徽"/>
        <d d1="101221005" d2="黟县" d3="yixian" d4="安徽"/>
        <d d1="101221006" d2="歙县" d3="shexian" d4="安徽"/>
        <d d1="101221007" d2="休宁" d3="xiuning" d4="安徽"/>
        <d d1="101221008" d2="黄山风景区" d3="huangshanfengjingqu" d4="安徽"/>
        <d d1="101221101" d2="滁州" d3="chuzhou" d4="安徽"/>
        <d d1="101221102" d2="凤阳" d3="fengyang" d4="安徽"/>
        <d d1="101221103" d2="明光" d3="mingguang" d4="安徽"/>
        <d d1="101221104" d2="定远" d3="dingyuan" d4="安徽"/>
        <d d1="101221105" d2="全椒" d3="quanjiao" d4="安徽"/>
        <d d1="101221106" d2="来安" d3="laian" d4="安徽"/>
        <d d1="101221107" d2="天长" d3="tianchang" d4="安徽"/>
        <d d1="101221201" d2="淮北" d3="huaibei" d4="安徽"/>
        <d d1="101221202" d2="濉溪" d3="suixi" d4="安徽"/>
        <d d1="101221301" d2="铜陵" d3="tongling" d4="安徽"/>
        <d d1="101221401" d2="宣城" d3="xuancheng" d4="安徽"/>
        <d d1="101221402" d2="泾县" d3="jingxian" d4="安徽"/>
        <d d1="101221403" d2="旌德" d3="jingde" d4="安徽"/>
        <d d1="101221404" d2="宁国" d3="ningguo" d4="安徽"/>
        <d d1="101221405" d2="绩溪" d3="jixi" d4="安徽"/>
        <d d1="101221406" d2="广德" d3="guangde" d4="安徽"/>
        <d d1="101221407" d2="郎溪" d3="langxi" d4="安徽"/>
        <d d1="101221501" d2="六安" d3="luan" d4="安徽"/>
        <d d1="101221502" d2="霍邱" d3="huoqiu" d4="安徽"/>
        <d d1="101221503" d2="寿县" d3="shouxian" d4="安徽"/>
        <d d1="101221505" d2="金寨" d3="jinzhai" d4="安徽"/>
        <d d1="101221506" d2="霍山" d3="huoshan" d4="安徽"/>
        <d d1="101221507" d2="舒城" d3="shucheng" d4="安徽"/>
        <d d1="101221601" d2="巢湖" d3="chaohu" d4="安徽"/>
        <d d1="101221602" d2="庐江" d3="lujiang" d4="安徽"/>
        <d d1="101221603" d2="无为" d3="wuwei" d4="安徽"/>
        <d d1="101221604" d2="含山" d3="hanshan" d4="安徽"/>
        <d d1="101221605" d2="和县" d3="hexian" d4="安徽"/>
        <d d1="101221701" d2="池州" d3="chizhou" d4="安徽"/>
        <d d1="101221702" d2="东至" d3="dongzhi" d4="安徽"/>
        <d d1="101221703" d2="青阳" d3="qingyang" d4="安徽"/>
        <d d1="101221704" d2="九华山" d3="jiuhuashan" d4="安徽"/>
        <d d1="101221705" d2="石台" d3="shitai" d4="安徽"/>
    </c>
  • 实体类对应
package com.xiaojinzi.dataobject;

import lombok.Data;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/4
 * @description 城市信息
 */
@Data
@XmlRootElement(name = "d")
@XmlAccessorType(XmlAccessType.FIELD)
public class City {

    /** 城市行政区代码 .*/
    @XmlAttribute(name = "d1")
    private String cityId;

    /** 城市名称 .*/
    @XmlAttribute(name = "d2")
    private String cityName;

    /** 城市中文拼音 .*/
    @XmlAttribute(name = "d3")
    private String cityNamePy;

    /** 省区 .*/
    @XmlAttribute(name = "d4")
    private String province;
}


package com.xiaojinzi.dataobject;

import lombok.Data;

import javax.xml.bind.annotation.*;
import java.util.List;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/4
 * @description 城市集合
 */
@Data
@XmlRootElement(name = "c")
@XmlAccessorType(XmlAccessType.FIELD)
public class CityList {

    /** 城市结合 .*/
    @XmlElement(name = "d")
    private List<City> cityList;
}

  • 对象转换
package com.xiaojinzi.utils;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.Reader;
import java.io.StringReader;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/4
 * @description Xml对象转换
 */
public class Xml2ObjList {

    /**
     * 根据类及文件地址进行xml与obj进行pojo转换
     * @param clazz
     * @param xmlStr
     * @return
     * @throws Exception
     */
    public static Object xml2Obj(Class<?> clazz, String xmlStr) throws Exception{
        Object objXml = null;
        Reader reader = null;

        // XML 对象 转换
        JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        reader = new StringReader(xmlStr);
        objXml = unmarshaller.unmarshal(reader);

        // 流关闭
        if(null != reader){
            reader.close();
        }

        return objXml;
    }
}

  • 城市接口
package com.xiaojinzi.services.impl;

import com.xiaojinzi.dataobject.City;
import com.xiaojinzi.dataobject.CityList;
import com.xiaojinzi.services.CityDataService;
import com.xiaojinzi.utils.Xml2ObjList;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/4
 * @description
 */
@Service
public class CityDataServiceImpl implements CityDataService {

    /**
     * 城市列表获取
     * @return
     * @throws Exception
     */
    @Override
    public List<City> cityList() throws Exception {

        // 获取xml
        Resource resource = new ClassPathResource("citylist.xml");
        BufferedReader bc = new BufferedReader(new InputStreamReader(resource.getInputStream()));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        while ((line = bc.readLine())!=null){
            buffer.append(line);
        }
        bc.close();

        //xmlstr转化obj
        CityList cityList = (CityList) Xml2ObjList.xml2Obj(CityList.class,buffer.toString());

        return cityList.getCityList();
    }
}

  • 数据入库
    /**
     * 同步城市天气数据
     * @param cityName
     */
    @Override
    public void weatherDataSyncByCityName(String cityName) {
        /** 城市名称自动同步 .*/
        String uri = weatherApiConfig.getUrl() +  "city="  + cityName;
        saveWeatherData(uri);
    }


    /**
     * 存储
     * @param uri
     */
    private void saveWeatherData(String uri){

        String key = uri;

        /** 返回对象转换 .*/
        String jsonPaser = null;

        /** 内容数据库中获值 .*/
        ValueOperations<String, String> ops =  stringRedisTemplate.opsForValue();

        /** 存储数据入库 .*/
        /** 获取返回结果 .*/
        ResponseEntity<String> result = restTemplate.getForEntity(uri,String.class);
        if(result.getStatusCodeValue() == 200) {
            jsonPaser = result.getBody();
        }else {
            jsonPaser = null;
        }

        ops.set(key,jsonPaser,weatherApiConfig.getReTimeout(), TimeUnit.SECONDS);

    }
}

集成thymeleaf模板

注入thymeleaf模板,取消模板热加载缓存,控制层前后端数据以及视图呈现。

  • controller实现
package com.xiaojinzi.controller;

import com.xiaojinzi.services.CityDataService;
import com.xiaojinzi.services.WeatherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author 金全 JQ
 * @version 1.0 , 2018/6/5
 * @description 天气后台
 */
@Controller
public class WeatherReportController {

    @Autowired
    private WeatherService weatherService;

    @Autowired
    private CityDataService cityDataService;

    /**
     * 城市天气后台呈现
     * @param cityName
     * @param model
     * @return
     * @throws Exception
     */
    @GetMapping("/report/{cityName}")
    public ModelAndView weatherReportData(@PathVariable("cityName") String cityName, Model model)throws Exception{
        model.addAttribute("title", "天气预报");
        model.addAttribute("cityName", cityName);
        model.addAttribute("cityList",cityDataService.cityList());
        model.addAttribute("report", weatherService.getWeatherDataByCityName(cityName));
        return new ModelAndView("weather/report","reportData",model);
    }
}

<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>天气系统测试</title>
</head>
<body>
    <h1 th:text="${reportData.title}">天气情况</h1>
    <select>
        <option th:each="city : ${reportData.cityList}" th:text="${city.cityName}" th:value="${city.cityName}"
        th:selected="${city.cityName eq reportData.cityName}">

        </option>
    </select>
    <div>
        <p>
            城市:<span th:text="${reportData.report.data.city}"></span>
            空气指数:<span th:text="${reportData.report.data.aqi}"></span>
            温度:<span th:text="${reportData.report.data.wendu}"></span>
            友情提示:<span th:text="${reportData.report.data.ganmao}"></span>
        </p>
        <p>
            日期:<span th:text="${reportData.report.data.yesterday.date}"></span>
        </p>
        <p>
            最高温度:<span th:text="${reportData.report.data.yesterday.high}"></span>
            最低温度:<span th:text="${reportData.report.data.yesterday.low}"></span>
            风向:<span th:text="${reportData.report.data.yesterday.fx}"></span>
            风力:<span th:text="${reportData.report.data.yesterday.fl}"></span>
            天气情况:<span th:text="${reportData.report.data.yesterday.type}"></span>
        </p>
    </div>
    <div th:each="forecast : ${reportData.report.data.forecast}">
        <p>
            日期:<span th:text="${forecast.date}"></span>
        </p>
        <p>
            最高温度:<span th:text="${forecast.high}"></span>
            最低温度:<span th:text="${forecast.low}"></span>
            风向:<span th:text="${forecast.fengxiang}"></span>
            风力:<span th:text="${forecast.fengli}"></span>
            天气情况:<span th:text="${forecast.type}"></span>
        </p>
    </div>

</body>
</html>

  • 本篇博客原视频博主[从天气项目观看springcloud微服务智力]
  • 本篇博客撰写人: XiaoJinZi 转载请注明出处
  • 学生能力有限 附上邮箱: 986209501@qq.com 不足以及误处请大佬指责
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,973评论 3 119
  • 第四天任务: 今天主要任务完成精华模块的搭建。 精华页面的搭建 精华页面中全部界面的显示 日期的处理 热门评论的显...
    xx_cc阅读 3,065评论 11 33
  • 什么是自控力?我所理解的应该是通过自己的意志或习惯去改变自己不想接受的状态或陋习。 那么如何提高自己的自控力又是我...
    乐者生活阅读 199评论 0 0
  • 【同读一本书】2016-03-02-090《影响力》 正文5.4%:第一章影响力的武器 思考:开篇写的一小段,简单...
    楼小楼_elf阅读 331评论 5 0