一、理解json
1、JSON是什么?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式
本质就是具有特定格式的字符串
JSON数据已经是客户端与服务器端交互的最常用的选择, 已经很少使用xml来进行数据交互了
2、JSON数据格式
整体结构:
Json数组 : [ ]
Json对象: { }
Json数组的结构: [value1, value2, value3]
Json对象的结构: {key1:value1, key2:value2, key3:value3}
key的数据类型: 字符串
value的数据类型: 数值 ,字符串 , null,json数组 [],json对象 {}
例子:
[1, “ab”,[], {“n”:123, “b”:”abc”}] [1, “a”:3]
{“name”:”TOM”, “age”:12} {“aa”:“a”, 3}
3、.解析JSON
解析技术:
Android原生API : 编程相对麻烦
Gson框架 : 编码简洁, 项目首选
解析方向:
将java对象(包含集合)转换为json格式字符串(服务器)
将json格式字符串转换为java对象(包含集合)
4、使用工具(HiJson)查看json数据
二、使用原生api和Gson解析json
1、.解析JSON
解析技术:
Android原生API : 编程相对麻烦
Gson框架 : 编码简洁, 项目首选
解析方向:
将java对象(包含集合)转换为json格式字符串(服务器)
将json格式字符串转换为java对象(包含集合)
2、相关API
Android原生API:
JsonObject : json对象 { }
JSONObject(String json) : 将json字符串解析为json对象
Xxx getXxx(String name) : 根据name, 在json对象中得到对应的Value
JsonArray : json数组 []
JSONArray(String json) : 将json字符串解析为json数组
int length() : 得到json数组中元素的个数
Xxx getXxx(int index) : 根据下标得到json数组中对应的元素数据
Gson框架API
Gson : 能解析json数据的类
Gson() : 构造对象的方法
String toJson(Object src) : 将对象转换为对应格式的json字符串
T fromJson(String json, Type typeOfT) : 解析Json字符串, 得到对象
TypeToken<T> : 用来得到Type的类
protected TypeToken() : 受保存的构造方法
Type getType() : 得到类型对象
3、测试
测试解析{ }
{
"id":2, "name":"大虾",
"price":12.3,
"imagePath":"http://192.168.10.165:8080/L05_Server/images/f1.jpg"
}
测试解析[ ]
[
{
"id":1, "name":"大虾1",
"price":12.3,
"imagePath":"http://192.168.10.165:8080/f1.jpg"
},
{
"id":2, "name":"大虾2",
"price":12.5,
"imagePath":"http://192.168.10.165:8080/f2.jpg"
}
]
/*
1. 将json格式的字符串{}转换为Java对象, 使用原生API
2. 将json格式的字符串{}转换为Java对象, 使用GSON
3. 将json格式的字符串[]转换为Java对象的List, 使用原生API
4. 将json格式的字符串[]转换为Java对象的List, 使用GSON
5. 将Java对象转换为json字符串{}, 使用GSON
6. 将Java对象的List转换为json字符串[], 使用GSON
*/
public class MainActivity extends Activity{
/*
* 1. 将json格式的字符串{}转换为Java对象, 使用原生API
*/
public void testJsonToObject() throws JSONException {
String jsonString = "{\"id\":2, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"}";
//将json字符串封装为JSONObject对象
JSONObject jsonObject = new JSONObject(jsonString);
//从对象中根据key得到对应的value
int id = jsonObject.getInt("id");
String name = jsonObject.getString("name");
double price = jsonObject.getDouble("price");
String imagePath = jsonObject.getString("imagePath");
//封装ShopInfo对象
ShopInfo shopInfo = new ShopInfo(id, name, price, imagePath);
Log.e("TAG", shopInfo.toString());
}
/*
* 1. 将json格式的字符串{}转换为Java对象, 使用GSON
*/
public void testJsonToObject2() {
String jsonString = "{\"id\":3, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"}";
ShopInfo shopInfo = new Gson().fromJson(jsonString, ShopInfo.class);
Log.e("TAG", shopInfo.toString());
}
/*
* 3. 将json格式的字符串[]转换为Java对象的List, 使用原生API
*/
public void testJsonToList() throws JSONException {
String jsonString = "[{\"id\":3, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"},"
+ "{\"id\":5, \"name\":\"大虾2\", \"price\":128.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f2.jpg\"}]";
List<ShopInfo> list = new ArrayList<ShopInfo>();
//1. 将json字符串包装JSONArray对象
JSONArray jsonArray = new JSONArray(jsonString);
//2. 遍历JSONArray对象所有元素(JSONObject), 并将每个元素封装为shopInfo, 并添加到List
for(int i=0;i<jsonArray.length();i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
//从对象中根据key得到对应的value
int id = jsonObject.getInt("id");
String name = jsonObject.getString("name");
double price = jsonObject.getDouble("price");
String imagePath = jsonObject.getString("imagePath");
//封装ShopInfo对象
ShopInfo shopInfo = new ShopInfo(id, name, price, imagePath);
list.add(shopInfo);
}
Log.e("TAG", list.toString());
}
/*
* 4. 将json格式的字符串[]转换为Java对象的List, 使用GSON
*/
public void testJsonToList2() throws JSONException {
String jsonString = "[{\"id\":4, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"},"
+ "{\"id\":6, \"name\":\"大虾2\", \"price\":128.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f2.jpg\"}]";
List<ShopInfo> list = new Gson().fromJson(jsonString, new TypeToken<List<ShopInfo>>(){}.getType());
Log.e("TAG", list.toString());
}
/*
5. 将Java对象转换为json字符串{}, 使用GSON
*/
public void testObjectToJson() {
ShopInfo info = new ShopInfo(3, "KK", 1000, "http://www.sina.com");
String json = new Gson().toJson(info);
Log.e("TAG", json);
}
/*
6. 将Java对象的List转换为json字符串[], 使用GSON
*/
public void testListToJson() {
List<ShopInfo> list = new ArrayList<ShopInfo>();
list.add(new ShopInfo(3, "KK", 1000, "http://www.sina.com"));
list.add(new ShopInfo(4, "KK2", 2000, "http://www.sina.com222"));
String json = new Gson().toJson(list);
Log.e("TAG", json);
}
public void testJsonToMap() {
String jsonString = "{\"my name\":\"大虾\", \"1\":12}";
Map<String, Object> map = new Gson().fromJson(jsonString, new TypeToken<Map<String, Object>>(){}.getType());
Log.e("TAG", map.toString());
}
}
3、自己写Gson可以解析的bean
一、json数据
{
"data": [
{
"children": [
{
"id": 10007,
"title": "北京",
"type": 1,
"url": "/static/api/news/10007/list_1.json"
},
{
"id": 10006,
"title": "中国",
"type": 1,
"url": "/static/api/news/10006/list_5.json"
},
{
"id": 10008,
"title": "国际",
"type": 1,
"url": "/static/api/news/10008/list_7.json"
},
{
"id": 10014,
"title": "文娱",
"type": 1,
"url": "/static/api/news/10014/list_3.json"
},
{
"id": 10010,
"title": "体育",
"type": 1,
"url": "/static/api/news/10010/list_3.json"
},
{
"id": 10091,
"title": "生活",
"type": 1,
"url": "/static/api/news/10091/list_1.json"
},
{
"id": 10012,
"title": "旅游",
"type": 1,
"url": "/static/api/news/10012/list_3.json"
},
{
"id": 10095,
"title": "科技",
"type": 1,
"url": "/static/api/news/10095/list_1.json"
},
{
"id": 10009,
"title": "军事",
"type": 1,
"url": "/static/api/news/10009/list_3.json"
},
{
"id": 10011,
"title": "财经",
"type": 1,
"url": "/static/api/news/10011/list_3.json"
},
{
"id": 10093,
"title": "女性",
"type": 1,
"url": "/static/api/news/10093/list_1.json"
},
{
"id": 10192,
"title": "倍儿逗",
"type": 1,
"url": "/static/api/news/10192/list_1.json"
}
],
"id": 10000,
"title": "新闻",
"type": 1
},
{
"id": 10002,
"title": "专题",
"type": 10,
"url": "/static/api/news/10002/list_1.json",
"url1": "/static/api/news/10002/list1_1.json"
},
{
"id": 10003,
"title": "组图",
"type": 2,
"url": "/static/api/news/10003/list_1.json"
},
{
"dayurl": "/static/api/news/comment/day_1.json",
"excurl": "/static/api/news/comment/exc_1.json",
"id": 10004,
"title": "互动",
"type": 3,
"weekurl": "/static/api/news/comment/week_1.json"
},
{
"id": 10005,
"title": "投票",
"type": 4,
"url": "/static/api/news/vote/vote_1.json"
}
],
"extend": [
10007,
10006,
10008,
10014,
10091,
10010,
10192,
10009,
10095,
10093,
10012,
10011
],
"retcode": 200
}
查看JSON工具:
HiJson 2.1.2_jdk32.exe
HiJson 2.1.2_jdk64.exe
二、根据json格式自己写bean,Gson也可以解析额bean
/**
* 手动写json解析对应的对象
*
* Gson也能解析这个bean
*/
public class NewsCenterPagerBean2 {
private List<DetailPagerData> data;
private List extend;
private int retcode;
public List<DetailPagerData> getData() {
return data;
}
public void setData(List<DetailPagerData> data) {
this.data = data;
}
public List getExtend() {
return extend;
}
public void setExtend(List extend) {
this.extend = extend;
}
public int getRetcode() {
return retcode;
}
public void setRetcode(int retcode) {
this.retcode = retcode;
}
@Override
public String toString() {
return "NewsCenterPagerBean2{" +
"data=" + data +
", extend=" + extend +
", retcode=" + retcode +
'}';
}
public static class DetailPagerData{
private int id;
private String title;
private int type;
private String url;
private String url1;
private String dayurl;
private String excurl;
private String weekurl;
private List<ChildrenData> children;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrl1() {
return url1;
}
public void setUrl1(String url1) {
this.url1 = url1;
}
public String getDayurl() {
return dayurl;
}
public void setDayurl(String dayurl) {
this.dayurl = dayurl;
}
public String getExcurl() {
return excurl;
}
public void setExcurl(String excurl) {
this.excurl = excurl;
}
public String getWeekurl() {
return weekurl;
}
public void setWeekurl(String weekurl) {
this.weekurl = weekurl;
}
public List<ChildrenData> getChildren() {
return children;
}
public void setChildren(List<ChildrenData> children) {
this.children = children;
}
@Override
public String toString() {
return "DetailPagerData{" +
"id=" + id +
", title='" + title + '\'' +
", type=" + type +
", url='" + url + '\'' +
", url1='" + url1 + '\'' +
", dayurl='" + dayurl + '\'' +
", excurl='" + excurl + '\'' +
", weekurl='" + weekurl + '\'' +
", children=" + children +
'}';
}
public static class ChildrenData{
private int id;
private String title;
private int type;
private String url;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "ChildrenData{" +
"id=" + id +
", title='" + title + '\'' +
", type=" + type +
", url='" + url + '\'' +
'}';
}
}
}
}
写bean的方法:类名可以自己随便定义,但是属性必须和json对应。
三、使用系统工具解析json为对象
/**
* 使用Android系统自带的API解析json数据
*
* @param json
* @return
*/
private NewsCenterPagerBean2 parsedJson2(String json) {
NewsCenterPagerBean2 bean2 = new NewsCenterPagerBean2();
try {
JSONObject object = new JSONObject(json);
/**
* 用getInt()访问不存在的字段就会报错,用optInt就算以后服务器不返回这个字段了也不会报错,只是得不到内容
*/
int retcode = object.optInt("retcode");
bean2.setRetcode(retcode);//retcode字段解析成功
JSONArray data = object.optJSONArray("data");
//判断是否为空
if (data != null && data.length() > 0) {
List<NewsCenterPagerBean2.DetailPagerData> detailPagerDatas = new ArrayList<>();
//设置列表数据
bean2.setData(detailPagerDatas);
//for循环,解析每条数据
for (int i = 0; i < data.length(); i++) {
JSONObject jsonObject = (JSONObject) data.get(i);
NewsCenterPagerBean2.DetailPagerData detailPagerData = new NewsCenterPagerBean2.DetailPagerData();
//添加到集合中
detailPagerDatas.add(detailPagerData);
int id = jsonObject.optInt("id");
detailPagerData.setId(id);
int type = jsonObject.optInt("type");
detailPagerData.setType(type);
String title = jsonObject.optString("title");
detailPagerData.setTitle(title);
String url = jsonObject.optString("url");
detailPagerData.setUrl(url);
String url1 = jsonObject.optString("url1");
detailPagerData.setUrl1(url1);
String dayurl = jsonObject.optString("dayurl");
detailPagerData.setDayurl(dayurl);
String excurl = jsonObject.optString("excurl");
detailPagerData.setExcurl(excurl);
String weekurl = jsonObject.optString("weekurl");
detailPagerData.setWeekurl(weekurl);
JSONArray children = jsonObject.optJSONArray("children");
if (children != null && children.length() > 0) {
List<NewsCenterPagerBean2.DetailPagerData.ChildrenData> childrenDatas = new ArrayList<>();
//设置集合-ChildrenData
detailPagerData.setChildren(childrenDatas);
for (int j = 0; j < children.length(); j++) {
JSONObject childrenitem = (JSONObject) children.get(j);
NewsCenterPagerBean2.DetailPagerData.ChildrenData childrenData = new NewsCenterPagerBean2.DetailPagerData.ChildrenData();
//添加到集合中
childrenDatas.add(childrenData);
int childId = childrenitem.optInt("id");
childrenData.setId(childId);
String childTitle = childrenitem.optString("title");
childrenData.setTitle(childTitle);
String childUrl = childrenitem.optString("url");
childrenData.setUrl(childUrl);
int childType = childrenitem.optInt("type");
childrenData.setType(childType);
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return bean2;
}