一、使用JSONObject处理网络数据
文章底部为测试使用的JSON字符串获取方法。
1. JSON使用格式如下,使用逗号分隔
- JSON 键值对 “key” : “value” ,
- JSON 对象 {…} ,
- JSON 数组 […] ,
2. 主要使用方法
- getJSONObject() 获取JSON对象
- new JSONObject(str) JSON格式要求的字符串,返回一个JSON对象
- getString() 获取JSON字符串
- getInt() 获取JSON整型数据
下面我们来处理这一段JSON数据,并把id和name的数据显示到ListView当中。
代码部分,使用一个ListView来展示解析的JSON数组数据:
private void parseByJSONObject() {
new Thread(){
@Override
public void run() {
String str = getHttp();
//开始解析JSONObject :JSON对象, JSONArray:JSON数组
try {
//参数:满足JSON格式要求的字符串,获取JOSN对象
JSONObject jo = new JSONObject(str);
final int status = jo.getInt("status");//类似Map的获取方式
final String msg = jo.getString("msg");
Log.d("MainActivity", "status:" + status + " msg:" + msg);
//使用list保存JSON数组里的数据
List<Map<String, String>> mapList = new ArrayList<>();
JSONArray ja = jo.getJSONArray("data");
for(int i = 0; i < ja.length(); i++) {
//取出数组里的对象
JSONObject jsonObject = ja.getJSONObject(i);
String name = jsonObject.getString("name");
String id = jsonObject.getString("id");
Log.d("MainActivity", "name:" + name + " id:" + id);
//将数据存入Map
Map<String, String> map = new HashMap<>();
map.put("name", name);
map.put("id", id);
mapList.add(map);
}//这样JSON数据就处理完了
//这里使用一个ListView来展示解析的JSON数组数据
//创建SimpleAdapter()
String[] from = {"name", "id"};
int[] to = {R.id.item_name, R.id.item_id};
//参数1:上下文
//参数2:数据源 List<Map<String,Object>>
//参数3:布局资源 R.layout.item
//参数4:key数组,用于Map的键值获取
//参数5:TextView数组,获取到到Map的值会响应存放在对应的TextView中
final SimpleAdapter adapter =
new SimpleAdapter(JSONActivity.this, mapList, R.layout.item, from, to);
//显示到界面上
//此方法在子线程中调用,可以在内部处理界面的显示问题
//因为它相当于在此刻将操作权由子线程移交给了主线程
runOnUiThread(new Runnable() {
@Override
public void run() {
//在测试Activity的layout加入一个listView显示
listView.setAdapter(adapter);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}.start();
}
运行结果以及Log打印:
D/MainActivity: status:1 msg:成功
name:Tony老师聊shell——环境变量配置文件 id:1
name:数学知识在CSS动画中的应用 id:2
name:Oracle数据库开发必备利器之PL/SQL基础 id:3
name:Android见证消息推送时刻进阶篇 id:4
name:Avalon探索之旅基础教程——复杂绑定 id:5
name:Android-Service系列之断点续传下载 id:6
name:JUnit—Java单元测试必备工具 id:7
name:细说Java多线程之内存可见性 id:8
name:CSS动画实用技巧 id:9
name:C++远征之起航篇 id:10
二、使用GSON转换JSON对象
这里主要讲解利用GSON来操作Java对象和JSON数据之间的相互转换。
主要方法:
- toJson(object):将对象变为JSON字符串
- fromJson(JSONString, xxx.class):将JSON字符串转换为对象
1. toJson/fromJson的使用
1.1 在gradle中声明GSON的依赖库,然后sync工程
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
}
1.2 定义一个Java Bean来保存JSON数据:
public class Book {
private String title;
private String author;
private String content;
public Book() {}
public Book(String title, String author, String content) {
this.title = title;
this.author = author;
this.content = content;
}
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getAuthor() { return author; }
public void setAuthor(String author) { this.author = author; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", author='" + author + '\'' +
", content='" + content + '\'' +
'}';
}
}
1.3 代码实现操作:
private void gsonTest() {
//1.实例化一个Gson对象
final Gson gson = new Gson();
//2.使用toJson:将对象变为JSON字符串
Book book = new Book("《不能说的秘密》", "秘密", "这是秘密不能说。");
String str = gson.toJson(book);
Log.d("JSONActivity", str);
//3.使用fromJson:JSON字符串变为对象
Book book1 = gson.fromJson(str, Book.class);
Log.d("JSONActivity", book1 + "");
Log.d("JSONActivity", "标题:" + book1.getTitle() + ",内容:" + book1.getContent());
}
打印结果:
D/JSONActivity: {"author":"秘密","content":"这是秘密不能说。","title":"《不能说的秘密》"}
D/JSONActivity: Book{title='《不能说的秘密》', author='秘密', content='这是秘密不能说。'}
标题:《不能说的秘密》,内容:这是秘密不能说。
2. JSON内容处理
JSON获取的方法在最底部。
2.1 同样地要确保gradle中已经声明GSON的依赖库
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
}
2.2 定义一个Java Bean来保存JSON数据
Public class Test {
//1.定义JSON中对应的关键字
//2.定义无参数构造方法和三个参数的构造方法
//3.使用ctrl+n创建getter和setter方法
private int status;
private String msg;
//若data数据为数组,则定义成Book[] data;
private Book data;
public Test(int status, String msg, Book data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public Test() {
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Book getData() {
return data;
}
public void setData(Book data) {
this.data = data;
}
@Override
public String toString() {
return "Test{" +
"status=" + status +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
2.3 代码实现:
private void parseByGSON() {
new Thread(){
@Override
public void run() {
super.run();
final Gson gson = new Gson();
String str = getHttp();
Test test = gson.fromJson(str, Test.class);
Log.d("JSONActivity", test + "");
Log.d("JSONActivity", "Status:" + test.getStatus() +
" Msg:" + test.getMsg() +
" data" + test.getData() +
" Status" + test.getData().getTitle());
}
}.start();
}
打印结果:
对比JSON和GSON解析的方法可以看出,使用第三方的GSON解析JSON数据更加方便。
D/MainActivity: {"status":1,"data":{"title":"Tony\u8001\u5e08\u804ashell\u2014\u2014\u73af\u5883\u53d8\u91cf\u914d\u7f6e\u6587\u4ef6","author":"Tony","content":"\u672c\u8bfe\u7a0b\u662f\u300aTony\u8001\u5e08\u804ashell\u300b\u7cfb\u5217\u8bfe\u7a0b\u7684\u7b2c\u4e09\u7bc7\uff0c\u4e3a\u4f60\u5e26\u6765\u5e38\u7528\u7684\u73af\u5883\u53d8\u91cf\u914d\u7f6e\u6587\u4ef6\u7684\u4f7f\u7528\u3002"},"msg":"\u6210\u529f"}
D/JSONActivity: Test{status=1, msg='成功', data=Book{title='Tony老师聊shell——环境变量配置文件', author='Tony', content='本课程是《Tony老师聊shell》系列课程的第三篇,为你带来常用的环境变量配置文件的使用。'}}
D/JSONActivity: Status:1 Msg:成功 data:Book{title='Tony老师聊shell——环境变量配置文件', author='Tony', content='本课程是《Tony老师聊shell》系列课程的第三篇,为你带来常用的环境变量配置文件的使用。'} Title:Tony老师聊shell——环境变量配置文件
3. 将JSON数组转换为List对象
Gson gson = new Gson();
//GoodsModel可以是一个bean,或者数据库的entity。
//如果json数组内有多个对象,也会自动传入list
List<GoodsModel> goodsModel = gson.fromJson(json, new TypeToken<List<GoodsModel>>() {}.getType());
4. GsonFormat的使用
3.1 去设置里下载Android插件来自动生成Bean文件。
3.2 新建一个类,在文件中使用右键弹出菜单,选择Generate,选择GsonFormat
3.3 将JSON代码复制进GsonFormat
{
"status": 1,
"data": {
"title": "Tony老师聊shell——环境变量配置文件",
"author": "Tony",
"content": "本课程是《Tony老师聊shell》系列课程的第三篇,为你带来常用的环境变量配置文件的使用。"
},
"msg": "成功"
}
3.4 选择Bean的成员变量以及类型
3.5 GsonFormat生成的代码
附:JSON字符串获取的GET请求
private String getHttp() {
//因为网络请求是耗时操作,所以需要创建一个子线程来运行
//避免主UI线程卡死
try {
//HttpURLConnection
//1.实例化一个URL对象
//JSON示例URL地址:http://www.imooc.com/api/teacher?type=2&cid=1
//GSON示例URL地址:http://www.imooc.com/api/teacher?type=3&cid=1
URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");
//2.获取HttpURLConnection实例
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//3.设置和请求相关的属性
//请求方式
connection.setRequestMethod("GET");
//请求超时时长 ms
connection.setConnectTimeout(6000);
//4.获取响应码
// 200:成功/404:未请求到指定资源/500:服务器异常
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//5.判断响应码并获取响应数据(响应的正文)
//获取响应的流
InputStream is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// bis.read(b); 该方法返回值是int类型数据,代表的是实际读到的数据长度
byte[] b = new byte[1024];
int len;
//在循环中读取输入流
while( (len = bis.read(b)) != -1) {
//将字节数组里面的内容存/写入缓存流
//参数1:待写入的数组
//参数2:起点
//参数3:长度
baos.write(b, 0, len);
}
//关闭资源
baos.flush();
bis.close();
baos.close();
//6.输出获取到到数据
String msg = new String(baos.toByteArray());
Log.d("MainActivity", msg);
return msg;
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}