承接上篇文中,讲到eclipse开发环境中Gson的引入和基本使用;下面将讲述java中的网络编程和Gson对json字符串的解析:
/** * 向指定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;
}
/** * 向指定 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" //日落时间
}
}
我们需要构造相应结构的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());
}
}