Java中使用Gson解析json数据

前言

    承接上篇文中,讲到eclipse开发环境中Gson的引入和基本使用;下面将讲述java中的网络编程和Gson对json字符串的解析:
  • java 发送Http Get请求
  • java 发送Http send请求
  • 请求返回json数据的类构造

发送Http Get请求

/** * 向指定URL发送GET方法的请求 * * @param url 发送请求的URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
// System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        return result;
    }

发送Http send请求

/** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */
    public static String sendPost(String baseUrl, String md5, String jsonStr) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        String result = "";

        try {
            URL realUrl = new URL(baseUrl + "?sign=" + md5);
            // 打开和URL之间的连接
            // URLConnection conn = realUrl.openConnection();
            HttpURLConnection conn = (HttpURLConnection) realUrl
                    .openConnection();

            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setInstanceFollowRedirects(true);
            conn.setUseCaches(true);

            conn.setRequestMethod("POST");
            conn.setConnectTimeout(18000);
            conn.setInstanceFollowRedirects(true);
            conn.setRequestProperty("Accept", "application/json");// 设置接受报文的格式
            conn.setRequestProperty("Content-Type", "text/plain");// 设置发送的格式

            // 获取URLConnection对象对应的输出流
            conn.connect();

            out = new OutputStreamWriter(conn.getOutputStream());
            out.write(jsonStr);
            out.flush();

            in = new BufferedReader(new InputStreamReader(
                    conn.getInputStream(), "UTF-8"));

            String line = null;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        return result;
    }

实例测试

可以在百度API Store中请求一些天气状况数据,返回json字符串;
eg:

public class MainTest {
    public static void main(String[] args) {
        // api store随便查找的请求的天气数据
        final String baseUrl = "http://apistore.baidu.com/microservice/weather";
        final String param = "citypinyin=zhengzhou";
        final String jsonStr = HttpUtil.sendGet(baseUrl, param);

        System.out.println(jsonStr);
    }
}

返回得到的是json字符串:

{
errNum: 0,
errMsg: "success",
retData: {
   city: "北京", //城市
   pinyin: "beijing", //城市拼音
   citycode: "101010100",  //城市编码 
   date: "15-02-11", //日期
   time: "11:00", //发布时间
   postCode: "100000", //邮编
   longitude: 116.391, //经度
   latitude: 39.904, //维度
   altitude: "33", //海拔 
   weather: "晴",  //天气情况
   temp: "10", //气温
   l_tmp: "-4", //最低气温
   h_tmp: "10", //最高气温
   WD: "无持续风向",  //风向
   WS: "微风(<10m/h)", //风力
   sunrise: "07:12", //日出时间
   sunset: "17:44" //日落时间
  }    
}

json字符串转java对象的类构造

    我们需要构造相应结构的java类,并生成相应的对象,方可使用Gson进行相应的解析,根据上述请求的得到的json字符串,具体构造方法如下:
    <1> 将json字符串中的单一键值对(key-value)表示成类的属性;
    <2> 将json字符串中的“{}”包围的结构,构造成另一个类;
    <3> 将json字符串中的"[]"包围的结构,构造成数组,通常使用List<>。
    <4> 构造类中的属性名称,一定要与json字符串中的名称一致(***特别重要, 由Gson的方法所限制***)

    那么,对于上述的天气json字符串,我们的构造过程如下所示:

构造整体类结构

    (1) 构造一个Weather类,含有3个私有属性:(***注意:属性名称和json字符串中的key的名称一样***);
    (2) 添加相应的构造方法、Getter和Setter方法;
    private int errNum;             // 错误标志
    private String errMsg;          // 错误信息
    private RetData retData;        // 对象类型的请求具体数据

具体结构如下:

public class Weather {
    private int errNum;             // 错误标志
    private String errMsg;          // 错误信息
    private RetData retData;        // 请求具体数据

    public Weather() {
    }

    public Weather(int errNum, String errMsg, RetData retData) {
        this.errNum = errNum;
        this.errMsg = errMsg;
        this.retData = retData;
    }

    public int getErrNum() {
        return errNum;
    }

    public void setErrNum(int errNum) {
        this.errNum = errNum;
    }

    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    public RetData getRetData() {
        return retData;
    }

    public void setRetData(RetData retData) {
        this.retData = retData;
    }
}

同理,json字符串中的retData天气数据的构造如下:

public class RetData {
    private String city;            // 城市名称
    private String pinyin;          // 城市拼音
    private String citycode;        // 城市编号
    private String date;            // 日期
    private String time;            // 时间
    private String postCode;        // 邮编
    private String longitude;       // 经度
    private String latitude;        // 纬度
    private String altitude;        // 海拔
    private String weather;         // 天气状况
    private String temp;            // 温度
    private String l_tmp;           // 低温
    private String h_tmp;           // 高温
    private String WD;              // 风向
    private String WS;              // 风速
    private String sunrise;         // 日出时间
    private String sunset;          // 日落时间

    public RetData() {
    }

    public RetData(String city, String pinyin, String citycode, String date, String time, String postCode, String longitude, String latitude, String altitude, String weather, String temp, String l_tmp, String h_tmp, String WD, String WS, String sunrise, String sunset) {
        this.city = city;
        this.pinyin = pinyin;
        this.citycode = citycode;
        this.date = date;
        this.time = time;
        this.postCode = postCode;
        this.longitude = longitude;
        this.latitude = latitude;
        this.altitude = altitude;
        this.weather = weather;
        this.temp = temp;
        this.l_tmp = l_tmp;
        this.h_tmp = h_tmp;
        this.WD = WD;
        this.WS = WS;
        this.sunrise = sunrise;
        this.sunset = sunset;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getPinyin() {
        return pinyin;
    }

    public void setPinyin(String pinyin) {
        this.pinyin = pinyin;
    }

    public String getCitycode() {
        return citycode;
    }

    public void setCitycode(String citycode) {
        this.citycode = citycode;
    }

    public String getDate() {
        return date;
    }

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

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getPostCode() {
        return postCode;
    }

    public void setPostCode(String postCode) {
        this.postCode = postCode;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getAltitude() {
        return altitude;
    }

    public void setAltitude(String altitude) {
        this.altitude = altitude;
    }

    public String getWeather() {
        return weather;
    }

    public void setWeather(String weather) {
        this.weather = weather;
    }

    public String getTemp() {
        return temp;
    }

    public void setTemp(String temp) {
        this.temp = temp;
    }

    public String getL_tmp() {
        return l_tmp;
    }

    public void setL_tmp(String l_tmp) {
        this.l_tmp = l_tmp;
    }

    public String getH_tmp() {
        return h_tmp;
    }

    public void setH_tmp(String h_tmp) {
        this.h_tmp = h_tmp;
    }

    public String getWD() {
        return WD;
    }

    public void setWD(String WD) {
        this.WD = WD;
    }

    public String getWS() {
        return WS;
    }

    public void setWS(String WS) {
        this.WS = WS;
    }

    public String getSunrise() {
        return sunrise;
    }

    public void setSunrise(String sunrise) {
        this.sunrise = sunrise;
    }

    public String getSunset() {
        return sunset;
    }

    public void setSunset(String sunset) {
        this.sunset = sunset;
    }
}
    至此,我们的类结构的构造定义完成了,下面调用Gson的`fromJson()方法`(具体原理是java的反射机制)便可以生成相应的变量在内存中使用。

综合测试

public class MainTest {
    public static void main(String[] args) {
        // api store随便查找的请求的天气数据
        final String baseUrl = "http://apistore.baidu.com/microservice/weather";
        final String param = "citypinyin=zhengzhou";
        final String jsonStr = HttpUtil.sendGet(baseUrl, param);

        System.out.println(jsonStr);

        Gson gson = new Gson();
        Weather weather = gson.fromJson(jsonStr, Weather.class);
        RetData retData = weather.getRetData();

        System.out.println("weather = " + weather.getErrNum());
        System.out.println("weather = " + weather.getErrMsg());

        System.out.println("retData = " + retData.getH_tmp());
        System.out.println("retData = " + retData.getL_tmp());

        System.out.println("retData = " + retData.getTemp());
        System.out.println("retData = " + retData.getWD());
        System.out.println("retData = " + retData.getWeather());
        System.out.println("retData = " + retData.getWeather());
    }
}

你可能感兴趣的:(http,gson,get,post,java对象)