SpringBoot搭建天氣預報微服務系統(單體架構)

前言

本系列文章將簡單的學習SpringCloud微服務相關知識,其實也是因爲時間的原因,一直拖到現在,遂打算趁着假期,決定記錄下來。

從天氣預報微服務系統的單體架構——>分佈式架構的演變過程中,一步一步,由淺及深的學習SpringCloud微服務的思想與其實現的組件。

本系列文章分爲以下幾個章節:

項目源碼已上傳至Github.

開發環境

  • JDK 1.8
  • IDEA 2017.3
  • Gradle 4
  • HttpClient 4.5.3
  • SpringBoot 2.0.0.RELEASE
//依賴關係
dependencies {
    //該依賴用於編譯階段
    compile('org.springframework.boot:spring-boot-starter-web')
    //HttpClient
    compile('org.apache.httpcomponents:httpclient:4.5.3')

    //該依賴用於測試階段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

開發需求

天氣預報項目的功能特別簡單。即用戶可以通過城市名稱查詢對應的城市天氣。

關於天氣預報數據的來源

我們使用網上免費的第三方天氣API服務提供商。當然對於的缺點就是不穩定,隨時可能掛掉,但是足以應付我們的開發學習。

開發過程

項目結構

這裏寫圖片描述

從返回JSON數據建立對應的實體類

我們利用Postman發送天氣請求。

http://wthrcdn.etouch.cn/weather_mini?citykey=101280101

這裏寫圖片描述

返回數據如下(部分):

{
    "data": {
        "yesterday": {
            "date": "27日星期五",
            "high": "高溫 26℃",
            "fx": "無持續風向",
            "low": "低溫 22℃",
            "fl": "<![CDATA[<3級]]>",
            "type": "陣雨"
        },
        "city": "廣州",
        "aqi": "77",
        "forecast": [
            {
                "date": "28日星期六",
                "high": "高溫 26℃",
                "fengli": "<![CDATA[<3級]]>",
                "low": "低溫 21℃",
                "fengxiang": "無持續風向",
                "type": "陣雨"
            },
            {
                "date": "29日星期天",
                "high": "高溫 27℃",
                "fengli": "<![CDATA[<3級]]>",
                "low": "低溫 23℃",
                "fengxiang": "無持續風向",
                "type": "陣雨"
            }
        ],
        "ganmao": "各項氣象條件適宜,無明顯降溫過程,發生感冒機率較低。",
        "wendu": "24"
    },
    "status": 1000,
    "desc": "OK"
}

可以很容易的發現,可以建立四個實體類。

  • Forecast
    private String date;
    private String high;
    private String fengli;
    private String low;
    private String fengxiang;
    private String type;
  • Weather
    private Yesterday yesterday;
    private String city;
    private String aqi;
    private List<Forecast> forecast;
    private String ganmao;
    private String wendu;
  • WeatherResponse
    private Weather data;
    private Integer status;
    private String desc;
  • Yesterday
    private String date;
    private String high;
    private String fx;
    private String low;
    private String fl;
    private String type;

建立天氣預報系統API

對於系統,我們只提供兩個請求方式。

  • 根據城市ID查詢天氣 /cityId/{cityId}
  • 根據城市名稱查詢天氣 /cityName/{cityName}
WeatherDataService
/**
 * @Author: cfx
 * @Description: 天氣數據接口
 * @Date: Created in 2018/4/5 10:38
 */
public interface WeatherDataService {
    /**
     * 根據城市Id查詢天氣
     * @param cityId
     * @return
     */
    WeatherResponse getDataByCityId(String cityId);

    /**
     * 根據城市名稱查詢天氣
     * @param cityName
     * @return
     */
    WeatherResponse getDataByCityName(String cityName);
}
WeatherDataServiceImpl
@Service
public class WeatherDataServiceImpl implements WeatherDataService {
    private static final String WEATHER_URI = "http://wthrcdn.etouch.cn/weather_mini?";

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public WeatherResponse getDataByCityId(String cityId) {
        String uri = WEATHER_URI + "citykey=" + cityId;
        return this.doGetWeather(uri);
    }

    @Override
    public WeatherResponse getDataByCityName(String cityName) {
        String uri = WEATHER_URI + "city=" + cityName;
        return this.doGetWeather(uri);
    }

    /**
     * 重構代碼
     * @param uri
     * @return
     */
    private WeatherResponse doGetWeather(String uri) {
        ResponseEntity<String> respString = restTemplate.getForEntity(uri,String.class);

        //將接口返回的Json字符串轉換成對象
        ObjectMapper mapper = new ObjectMapper();
        WeatherResponse resp = null;
        String strBody = null;

        if (respString.getStatusCodeValue() == 200) {
            strBody = respString.getBody();
        }

        try {
            resp = mapper.readValue(strBody,WeatherResponse.class);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return resp;
    }

}

視圖控制層

WeatherController
@RestController
@RequestMapping("/weather")
public class WeatherController {

    @Autowired
    private WeatherDataService weatherDataService;

    @GetMapping("/cityId/{cityId}")
    public WeatherResponse getWeatherByCityId(@PathVariable("cityId") String cityId) {
        return weatherDataService.getDataByCityId(cityId);
    }

    @GetMapping("/cityName/{cityName}")
    public WeatherResponse getWeatherByCityName(@PathVariable("cityName") String cityName) {
        return weatherDataService.getDataByCityName(cityName);
    }
}

RestTemplate模板配置

@Configuration
public class RestConfiguration {
    //啓動的時候要注意,由於我們在controller中注入了RestTemplate,所以啓動的時候需要實例化該類的一個實例
    @Autowired
    private RestTemplateBuilder builder;
    @Bean
    public  RestTemplate restTemplate() {
        return builder.build();
    }
}

運行

輸入http://localhost:8080/weather/cityId/101280601運行。
這裏寫圖片描述
至此,基於SpringBoot的單體結構的天氣預報系統大體就完成了,後面還會基於此加入Redis和Quartz來提高系統性能。

發佈了65 篇原創文章 · 獲贊 93 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章