springboot实战之使用接口查询天气

1、原理说明:

查询天气的api:https://www.sojson.com/open/api/weather/json.shtml?city=
直接在city=后面加上中文城市,就会返回json数据。

eg: https://www.sojson.com/open/api/weather/json.shtml?city=饶平 

{"date":"20180730","message":"Success !","status":200,"city":"广州","count":1,
"data":{"shidu":"96%","pm25":15.0,"pm10":31.0,"quality":"优","wendu":"26","ganmao":"各类人群可自由活动",
"yesterday":{"date":"29日星期日","sunrise":"05:55","high":"高温 35.0℃","low":"低温 27.0℃","sunset":"19:11","aqi":49.0,"fx":"无持续风向","fl":"<3级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"},
"forecast":[
{"date":"30日星期一","sunrise":"05:56","high":"高温 34.0℃","low":"低温 26.0℃","sunset":"19:10","aqi":46.0,"fx":"南风","fl":"3-4级","type":"雷阵雨","notice":"带好雨具,别在树下躲雨"},
{"date":"31日星期二","sunrise":"05:56","high":"高温 35.0℃","low":"低温 27.0℃","sunset":"19:10","aqi":54.0,"fx":"南风","fl":"3-4级","type":"雷阵雨","notice":"带好雨具,别在树下躲雨"},
{"date":"01日星期三","sunrise":"05:57","high":"高温 35.0℃","low":"低温 28.0℃","sunset":"19:09","aqi":59.0,"fx":"西南风","fl":"3-4级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"},
{"date":"02日星期四","sunrise":"05:57","high":"高温 35.0℃","low":"低温 27.0℃","sunset":"19:09","aqi":65.0,"fx":"无持续风向","fl":"<3级","type":"雷阵雨","notice":"带好雨具,别在树下躲雨"},
{"date":"03日星期五","sunrise":"05:57","high":"高温 35.0℃","low":"低温 27.0℃","sunset":"19:08","aqi":61.0,"fx":"东南风","fl":"3-4级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"}]}}

2、说明

    概要:该系统是供给查询天气的,todayWeather类是描述今天的天气的,Weather类是描述从昨天开始的天气到未来几天的天气,一般而言,利用city+date字段作为todayweather的id,利用city+date作为搜索Weather的值。查询天气时,当数据库不存在该数据的时候,直接访问 查询天气的api,然后会将该数据存储到数据库中去,但当不是第一次查询已经查过的内容的时候,是从数据库中读取出来,而不是去访问天气查询api,减少对天气查询api的访问次数。

  数据库说明:采用NoSQL的mongodb,想要运行该程序,需要先搭建好数据库环境,其中账号密码见application.properties文件。此外,本是不需要手动建立数据库的,但是,由于第一次查询的时候,需要访问数据库,所以需要手动建立数据库,最好是存在一条信息。

3、代码

项目的目录:

                                           

3.1 pom.xml

      <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>

3.2 application.properties

# 定位模板的目录
spring.mvc.view.prefix=classpath:/templates/

server.servlet.context-path=
server.port=8080
server.tomcat.uri-encoding=UTF-8
        
#mongodb  账号为:name 密码为:pass  数据库为test
spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test

3.3 TodayWeather 类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TodayWeather {
    @Id
    private String cityDate;

    private String city;
    private String date;
    private String week;
    private String shidu;
    private String pm25;
    private String pm10;
    private String quality;
    private String wendu;
    private String ganmao;
}

3.4 Weather类

package com.zhang.entity;

/*
   最近的天气
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Weather {
    //一般会有5个相同的,所以,不能作为@Id,只能作为寻找的关键字
    private String cityDate;

    private String city;
    private String date;
    private String sunrise;
    private String high;
    private String low;
    private String sunset;
    private String aqi;
    private String fx;
    private String fl;
    private String type;
    private String notice;
}

3.5 TodayWeatherRepository

package com.zhang.repository;

public interface TodayWeatherRepository extends MongoRepository<TodayWeather,String> {
   TodayWeather findByCityDate(String cityDate);
   void deleteByCityDate(String cityDate);
}

3.6 WeatherRepository

package com.zhang.repository;

public interface WeatherRepository  extends MongoRepository<Weather,String> {
     List<Weather> findAllByCityDate(String cityDate);
     void deleteAllByCityDate(String cityDate);
}

3.7 TodayWeatherService

package com.zhang.service;

@Service
public class TodayWeatherService {

    @Autowired
    private  TodayWeatherRepository todayWeatherRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    //获取
    public TodayWeather getTodayWeather(String cityAndDate)
    {
        TodayWeather weather = new TodayWeather();
        try {
            //连表都没建立.....可以找吗??
            /*if (todayWeatherRepository == null) {
                return null;
            }*/
            weather = todayWeatherRepository.findByCityDate(cityAndDate);
            if(weather == null)
            {
                System.out.println("weather = = null");
                return null;
            }
        }
        catch(MongoException e)
        {
           e.printStackTrace();
        }
        return weather;
    }


    //增加
    public void addTodayWeather(TodayWeather todayWeather)
    {
        try{
            System.out.println("addTodayWeather-----try");
            if(todayWeather != null)
                todayWeatherRepository.save(todayWeather);
            else
                System.out.println("something error");
        }
        catch(MongoException e)
        {
            System.out.println("addTodayWeather------Exception");
            e.printStackTrace();
        }
    }

    //删
    public void deleteTodayWeather(String cityAndDate)
    {
        try{
            todayWeatherRepository.deleteByCityDate(cityAndDate);
        }
        catch(MongoException e)
        {
            e.printStackTrace();
        }
    }


    //改/更新
    public void updateTodayWeather(TodayWeather todayweather)
    {
        try{
            todayWeatherRepository.save(todayweather);
        }
        catch(MongoException e)
        {
            e.printStackTrace();
        }
    }

}

3.8 WeatherService

package com.zhang.service;

@Service
public class WeatherService {
    @Autowired
    private WeatherRepository weatherRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    //获取 weather
    public List<Weather> getWeatherList(String cityDate)
    {
        return weatherRepository.findAllByCityDate(cityDate);
    }

    //增加 weather
    public void addWeatherList( List<Weather>  weathers)
    {
        for ( Weather w : weathers )
           weatherRepository.save(w);
    }

    //删除
    public void deleteWeatherList(String cityAndDate)
    {
        weatherRepository.deleteAllByCityDate(cityAndDate);
    }
}

3.9 ReturnWeather.java ==》是获取具体的天气数据的

package com.zhang.conmon;

@Component
public class ReturnWeather {

    private JsonNode json = null;
    private final String uri = "https://www.sojson.com/open/api/weather/json.shtml?city=";
    private boolean getJsonData(String city)
    {
        System.out.println("getJsonData中的city:="+city);
        //去 服务器 请求一个数据
        RestTemplate rest = new RestTemplate();
        //ResponseEntity<T>是Spring对HTTP请求响应的封装,
        // 包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。
        //String.class,表示希望返回的body类型是String
        ResponseEntity<String>  response = rest.getForEntity(uri + city, String.class);

        //查询为成功的状态码
        if (response.getStatusCodeValue() == 200)
        {
            String strBody = response.getBody();
            ObjectMapper mapper = new ObjectMapper();
            try {
                json = mapper.readTree(strBody);
                return true;
            } catch (IOException e) {
                System.out.print("json初始化失败");
                e.printStackTrace();
            }
        }
        return false;
    }

    //用city来获取今天的天气
    public TodayWeather getTodayWeather(String city)
    {
        if (json == null) {
            boolean judge = getJsonData(city);
            if (judge == false)
                return null;
        }
        TodayWeather result = new TodayWeather();
        try {
            JsonNode data = json.get("data");
            result.setShidu(data.get("shidu").toString());
            result.setGanmao(data.get("ganmao").toString());
            result.setPm10(data.get("pm10").toString());
            result.setPm25(data.get("pm25").toString());
            result.setQuality(data.get("quality").toString());
            result.setWendu(data.get("wendu").toString());

            String date="";
            Calendar now= Calendar.getInstance();
            date=date+now.get(Calendar.YEAR)+(now.get(Calendar.MONTH)+1)+now.get(Calendar.DATE);
            System.out.println("日期为: "+date);
            result.setDate(date);
            System.out.println("城市为:"+city);
            result.setCity(city);

            String[] weeks = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
            Calendar n=Calendar.getInstance();
            int index= n.get(Calendar.DAY_OF_WEEK)-1;
            result.setWeek(weeks[index]);
            System.out.println("星期为:"+result.getWeek());

            result.setCity(city);
            System.out.println("city为:"+result.getCity());

            result.setCityDate(city+date);
            System.out.println("cityAndDate为:"+result.getCityDate());

        } catch (Exception e) {
            System.out.println("获取当天天气状况失败");
            e.printStackTrace();
            return null;
        }
        return result;
    }


    //用JsonNode作为参数
    private Weather returnWth(JsonNode deal,String city) throws Exception
    {
        Weather result=new Weather();

        String date="";
        Calendar now= Calendar.getInstance();
        date=date+now.get(Calendar.YEAR)+(now.get(Calendar.MONTH)+1)+now.get(Calendar.DATE);
        // System.out.println("日期为: "+date);
        result.setDate(date);
        result.setCity(city);

        result.setCityDate(city+date);
       // System.out.println("weather: "+ result.getCityDate());

        result.setAqi(deal.get("aqi").toString());
        result.setDate(deal.get("date").toString());
        result.setFl(deal.get("fl").toString());
        result.setFx(deal.get("fx").toString());
        result.setHigh(deal.get("high").toString());
        result.setLow(deal.get("low").toString());
        result.setNotice(deal.get("notice").toString());
        result.setSunrise(deal.get("sunrise").toString());
        result.setSunset(deal.get("sunset").toString());
        result.setType(deal.get("type").toString());
        return result;
    }

    //通过city获取昨天天气和天气展望
    public Vector<Weather> getWeatherList(String city)
    {
        if(json==null)
        {
            boolean judge = getJsonData(city);
            if(judge==false)
                return null;
        }

        Vector<Weather>  result = new Vector<Weather>();
        try{
            JsonNode yd=json.get("data").get("yesterday");
            Weather yesterday = returnWth(yd,city);
            Weather forecast;
            result.add(yesterday);
            JsonNode fc= json.get("data").get("forecast");
            for(int i=0;i<5;i++)
            {
                //给returnWth的fc.get(i) 只是 forecast部分
                forecast= returnWth(fc.get(i),city);
                result.add(forecast);
            }

        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        return  result;
    }

}

3.10 WeatherController  ==》 接受处理 该网页的api

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

    @Autowired
    private ReturnWeather deal;
    @Autowired
    private TodayWeatherService todayWeatherService;
    @Autowired
    private WeatherService weatherService;

    @RequestMapping(value="/{city}",method = RequestMethod.GET)
    public String getWeatherInfo(@PathVariable("city")String city,Model model)
    {
        String date="";
        Calendar now= Calendar.getInstance();
        date=date+now.get(Calendar.YEAR)+(now.get(Calendar.MONTH)+1)+now.get(Calendar.DATE);

        //若是没有建立表格,这个操作有问题!!   手动建立一个表格,让其存在
        System.out.println("getWeatherInfo中的cityAndDate1: = "+city+date);
        TodayWeather weather = todayWeatherService.getTodayWeather(city+date);
        System.out.println("getWeatherInfo中的cityAndDate2: = "+city+date);
        List<Weather> weatherList = weatherService.getWeatherList(city+date);

        //也就是 在数据库中 没有 该数据
        if( weather == null )
        {
            ReturnWeather deal = new ReturnWeather();
            TodayWeather weatherToday = deal.getTodayWeather(city);
            List <Weather> weatherSet= deal.getWeatherList(city);
            weatherService.addWeatherList(weatherSet);
            if(weatherToday != null)
            {
                model.addAttribute("TodayWth",weatherToday);
                model.addAttribute("WthSet",weatherSet);
                todayWeatherService.addTodayWeather(weatherToday);
            }
            else
            {
                System.out.print("设置error");
                model.addAttribute("error","查询次数过快或城市名称不存在");
            }
        }
        else//如果在数据库中存在,就直接读取数据库中的数据
        {
            System.out.println("从数据库中直接读取的数据: "+city+date+" 的天气");
            model.addAttribute("TodayWth",weather);
            model.addAttribute("WthSet",weatherList);
        }
        //返回weather页面
        return "weather";
    }
}

3.11 前端页面

<!DOCTYPE html>
<html xmlns="http://www.thymeleaf.org" xmlns:th="http://www.springframework.org/schema/mvc">
<head>
    <title>weather forecast</title>
</head>
<body>

<h2>-----title------</h2>

<script th:inline="javascript">

    var todayWeatherTest = [[${TodayWth}]];
    var WthSetTest =  [[${WthSet}]] ;    //数组来的
    var errorTest = [[${error}]];

    if(todayWeatherTest!=null) {
        document.write("<h2>今日天气</h2>");
        document.write("时间:" + todayWeatherTest.date+todayWeatherTest.week);
        document.write("<br>");
        document.write("地点:" + todayWeatherTest.city);
        document.write("<br>");
        document.write("温度:" + todayWeatherTest.wendu);
        document.write("<br>");
        document.write("湿度:" + todayWeatherTest.shidu);
        document.write("<br>");
        document.write("温馨提示:" + todayWeatherTest.ganmao);
        document.write("<br>");
        document.write("空气质量:" + todayWeatherTest.quality);
        document.write("<br>");
        document.write("Pm2.5:" + todayWeatherTest.pm25);
        document.write("<br>");
        document.write("PM1.0:" + todayWeatherTest.pm10);
        document.write("<br>");

        if (WthSetTest != null) { 
            for (var i in WthSetTest) {
                if (i === 0)
                    document.write("<h2>昨日天气</h2>");
                else
                    document.write("<h2>天气展望</h2>");
                document.write("时间: " + WthSetTest[i].date + "<br>");
                document.write("日出:" + WthSetTest[i].sunrise + "<br>");
                document.write("最高气温:" + WthSetTest[i].sunrise + "<br>");
                document.write("最低气温:" + WthSetTest[i].sunset + "<br>");
                document.write("aqi:" + WthSetTest[i].aqi + "<br>");
                document.write("fx:" + WthSetTest[i].fx + "<br>");
                document.write("fl:" + WthSetTest[i].fl + "<br>");
                document.write("天气:" + WthSetTest[i].type + "<br>");
                document.write("温馨提示:" + WthSetTest[i].notice + "<br>");
            }

        }

        if (errorTest != null) {
            document.write(errorTest.toString());
        }
    }

</script>
</body>
</html>

4、坑

   4.1、有些城市返回的数据格式不太一样,部分数据不存在,例如:海南是缺少部分数据的,故是显示不了数据。

   4.2、在todayWeather中设置city和date为主键,本来命名为cityAndDate,但是,在repository层中写接口的时候,会造成误会,要改成cityDate或者其他不造成冲突的。

   4.3、mongodb的findAll功能,返回的数据将是List,不是Vector。

   4.4、前后端的数据交互:

        前端获得后端的数据采用 var test = [[${test}]]; 的形式。后端将数据加入到Model里面。

        后端只是简单将url的参数作为 数据使用,没有其他复杂交互。

   4.5 采用redis缓存的在接下来再继续完成。

5 、欢迎交流~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值