java调用天气API和JSON解析的那些事儿

人丑话不多:

直接上代码:

1.根据返回的json数据格式定义数据模型

import java.util.List;

//定义一个描述天气的类
public class WeatherForecastInfo {

    private Double pm25;
    private List<Forecast> mForecasts;

    public Double getPm25() {
        return pm25;
    }

    public void setPm25(Double pm25) {
        this.pm25 = pm25;
    }

    public List<Forecast> getmForecasts() {
        return mForecasts;
    }

    public void setmForecasts(List<Forecast> mForecasts) {
        this.mForecasts = mForecasts;
    }

    @Override
    public String toString() {
        return "天气信息[" +
                "pm25=" + pm25 +
                ", mForecasts=" + mForecasts +
                ']';
    }

    //定义一个内部类
    public static class Forecast{
        private String date;//时间
        private String high;//最高温
        private String low;//最低温
        private String fx;//风向
        private String fl;//风等级
        private String type;//天气类型
        private String notice;//温馨提示

        public String getDate() {
            return date;
        }

        public void setDate(String date) {
            this.date = date;
        }

        public String getHigh() {
            return high;
        }

        public void setHigh(String high) {
            this.high = high;
        }

        public String getLow() {
            return low;
        }

        public void setLow(String low) {
            this.low = low;
        }

        public String getFx() {
            return fx;
        }

        public void setFx(String fx) {
            this.fx = fx;
        }

        public String getFl() {
            return fl;
        }

        public void setFl(String fl) {
            this.fl = fl;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getNotice() {
            return notice;
        }

        public void setNotice(String notice) {
            this.notice = notice;
        }

        //重写toString方法
        @Override
        public String toString() {
            return "未来天气[" +
                    "日期='" + date + '\'' +
                    ", 最高温='" + high + '\'' +
                    ", 最低温='" + low + '\'' +
                    ", 风向='" + fx + '\'' +
                    ", 风等级='" + fl + '\'' +
                    ", 天气类型='" + type + '\'' +
                    ", 温馨提示='" + notice + '\'' +
                    ']';
        }
    }
    
}

2.编写Java代码进行json数据获取和解析

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

public class NetWorkActivity extends AppCompatActivity{
    private Button btn_getData;
    private Button btn_parseData;
    private TextView tv_result;
    private String result;

    //创建一个WeatherForecastInfo对象
    WeatherForecastInfo weatherForecastInfo=new WeatherForecastInfo();

    //创建一个Forecast集合
    List<WeatherForecastInfo.Forecast> forecastList=new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_network);
        //初始化控件
        initialView();
        //添加事件监听
        myClickListener();
    }

    //初始化控件
    public void initialView(){
        btn_getData=findViewById(R.id.btn_getData);
        btn_parseData=findViewById(R.id.btn_parseData);
        tv_result=findViewById(R.id.tv_result);
    }


    class MyOnClickListener implements View.OnClickListener{
        @Override
        public void onClick(View view) {
            switch (view.getId()){

                case R.id.btn_getData:
                    //获取天气的jason数据
                    //1.耗时操作必须放在线程中执行,否则报异常
                    //2.有网络请求的,必须在开启网络权限
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            requestDataByGet();
                        }
                    }).start();
                    break;
                case R.id.btn_parseData:
                    //解析天气的jason数据
                    handleJsonData(result);
                    showWeatherInfo(forecastList);
                    break;
            }
        }
    }


    //json数据解析
    private void handleJsonData(String result){
        //创建一个json对象,捕获异常
        try {

            JSONObject jsonObject=new JSONObject(result);
            //提取日期
            String date=jsonObject.getString("date");
            System.out.println("date:"+date);
            //提取城市
            String city=jsonObject.getString("city");
            System.out.println("city:"+city);
            //提取data数据
            JSONObject dataObject=jsonObject.getJSONObject("data");
            //提取data里面的pm25
            double pm25=dataObject.getDouble("pm25");
            weatherForecastInfo.setPm25(pm25);

            //提取data里面的未来天气
            //注意:forecast中的内容带有中括号[],所以要转化为JSONArray类型的对象
            JSONArray forecasts=dataObject.getJSONArray("forecast");

            //对forecast数组判空
            if (forecasts!=null&&forecasts.length()>0){
                //for循环来处理
                for (int index=0;index<forecasts.length();index++){
                    //提取出forecast中每个数组中的内容
                    JSONObject weather=forecasts.getJSONObject(index);
                    String mdate=weather.getString("date");//时间
                    String mhigh=weather.getString("high");//最高温
                    String mlow=weather.getString("low");//最低温
                    String mfx=weather.getString("fx");//风向
                    String mfl=weather.getString("fl");//风等级
                    String mtype=weather.getString("type");//天气类型
                    String mnotice=weather.getString("notice");//温馨提示
                    //创建WeatherForecastInfo中的内部类Forecast
                    WeatherForecastInfo.Forecast forecastItem=new WeatherForecastInfo.Forecast();
                    //设置Forecast中的数据
                    forecastItem.setDate(mdate);
                    forecastItem.setHigh(mhigh);
                    forecastItem.setLow(mlow);
                    forecastItem.setFx(mfx);
                    forecastItem.setFl(mfl);
                    forecastItem.setType(mtype);
                    forecastItem.setNotice(mnotice);
                    //最后将forecastItem添加到forecastList集合中
                    forecastList.add(forecastItem);
                }
                weatherForecastInfo.setmForecasts(forecastList);
            }

            tv_result.setText(weatherForecastInfo.toString());

        }catch (JSONException e){
            e.printStackTrace();
        }

    }

    //显示天气数据
    public void showWeatherInfo(List<WeatherForecastInfo.Forecast> forecastList){
        //将forecastList列表中的数据循环输出
        if (forecastList!=null){
            System.out.println(forecastList.toString());
        }
    }

    //get方法获取json的天气数据
    private void requestDataByGet() {
        try {
            String citiName="北京";
            String weather_url="https://www.sojson.com/open/api/weather/json.shtml?city="+getEncodeValue(citiName);
            URL url=new URL(weather_url);
            HttpURLConnection connection=(HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(30*1000);
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type","application/json");
            connection.setRequestProperty("Charset","UTF-8");
            connection.setRequestProperty("Accept-Charset","UTF-8");
            connection.connect();//发起连接

            //获取状态码
            int requestCode=connection.getResponseCode();
            System.out.println(requestCode);
            //获取返回信息
            String requestMessage=connection.getResponseMessage();
            System.out.println(requestMessage);

            //根据状态码进行处理
            if (requestCode==HttpURLConnection.HTTP_OK){
                //1.从connection中获得输入流
                InputStream inputStream=connection.getInputStream();
                //2.将输入流转换成字符串
                result=streamToString(inputStream);
                //3.更新UI必须在主线程中完成
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tv_result.setText(result);
                    }
                });
            }
            else {
                Log.e("TAG", "run:error code: "+requestCode+",message:"+requestMessage);
            }
        }catch (MalformedURLException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //post方法
    /*private void requestDataByPost() {
        try {
            URL url=new URL("https://www.sojson.com/open/api/weather/json.shtml");
            HttpURLConnection connection=(HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(30*1000);
            connection.setRequestMethod("Post");
            connection.setRequestProperty("Content-Type","application/json");
            connection.setRequestProperty("Charset","UTF-8");
            connection.setRequestProperty("Accept-Charset","UTF-8");

            connection.setDoOutput(true);
            connection.setDoInput(true);
            //是否使用缓存
            connection.setUseCaches(false);

            connection.connect();//发起连接

            String data="city="+getEncodeValue("北京");

            OutputStream outputStream=connection.getOutputStream();
            outputStream.write(data.getBytes());
            outputStream.flush();
            //最后关闭输入流
            outputStream.close();

            //获取状态码
            int requestCode=connection.getResponseCode();
            //获取返回信息
            String requestMessage=connection.getResponseMessage();
            //根据状态码进行处理
            if (requestCode==HttpURLConnection.HTTP_OK){
                //从connection中获得输入流
                InputStream inputStream=connection.getInputStream();
                //将输入流转换成字符串
                result=streamToString(inputStream);
                //3.更新UI必须在主线程中完成
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tv_result.setText(result);
                    }
                });

            }
            else {
                Log.e("TAG", "run:error code: "+requestCode+",message:"+requestMessage);
            }

        }catch (MalformedURLException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
*/


    //将编码转换成UTF编码
    public String getEncodeValue(String imooc){
        String encode=null;
        try {
            encode= URLEncoder.encode(imooc,"UTF-8");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return encode;
    }


    public void myClickListener(){
        MyOnClickListener myOnClickListener=new MyOnClickListener();
        btn_getData.setOnClickListener(myOnClickListener);
        btn_parseData.setOnClickListener(myOnClickListener);
    }

    //将输入流转换成字符串
    public String streamToString(InputStream inputStream){
        try{
            ByteArrayOutputStream baos=new ByteArrayOutputStream();
            byte[] buffer=new byte[1024];
            int len;
            while ((len=inputStream.read(buffer))!=-1){
                //byte数组、偏移量、数组长度
                baos.write(buffer,0,len);
            }
            //关闭输出流
            baos.close();
            //关闭输入流
            inputStream.close();
            //将输出流转换成字节数组
            byte[] byteArray=baos.toByteArray();
            //将字节数组转换成字符串,并进行返回
            return new String(byteArray);
        }catch (Exception e){
            Log.e("TAG",e.toString());
            return null;
        }
    }
}

运行情况:

09-17 11:34:05.830 3910-3910/com.example.jiaho.http I/System.out: date:20180917
    city:北京
09-17 11:34:05.834 3910-3910/com.example.jiaho.http I/System.out: [未来天气[日期='17日星期一', 最高温='高温 27.0℃', 最低温='低温 17.0℃', 风向='北风', 风等级='<3级', 天气类型='多云', 温馨提示='阴晴之间,谨防紫外线侵扰'], 未来天气[日期='18日星期二', 最高温='高温 25.0℃', 最低温='低温 17.0℃', 风向='西南风', 风等级='<3级', 天气类型='阴', 温馨提示='不要被阴云遮挡住好心情'], 未来天气[日期='19日星期三', 最高温='高温 26.0℃', 最低温='低温 19.0℃', 风向='南风', 风等级='<3级', 天气类型='多云', 温馨提示='阴晴之间,谨防紫外线侵扰'], 未来天气[日期='20日星期四', 最高温='高温 29.0℃', 最低温='低温 16.0℃', 风向='西北风', 风等级='<3级', 天气类型='多云', 温馨提示='阴晴之间,谨防紫外线侵扰'], 未来天气[日期='21日星期五', 最高温='高温 24.0℃', 最低温='低温 12.0℃', 风向='西风', 风等级='4-5级', 天气类型='晴', 温馨提示='愿你拥有比阳光明媚的心情']]

猜你喜欢

转载自blog.csdn.net/CjhLoveAndroid/article/details/82750915