【Android应用开发技术:网络通信】Android下的JSON处理

作者:郭孝星
微博:郭孝星的新浪微博
邮箱:guoxiaoxingv@163.com
博客:http://blog.csdn.net/allenwells
Github:https://github.com/guoxiaoxing

一 JSON基础

JSON全称是JavaScript 对象表示法(JavaScript Object Notation),它基 于 JavaScript 的一个子集, 它使用JavaScript语法来描述数据对象, 但是JSON 仍然独立于语言和平台。

JSON的主要优点如下所示:

  • 数据格式比较简单,易于读写,格式都是压缩的,占用带宽小。
  • 易于解析语言,客户端 JavaScript 可以简单地通过 eval() 进行 JSON 数据的读取。
  • 支 持 多 种 语 言, 包 括 ActionScript、C、C#、ColdFusion、Java、JavaScript、Perl、PHP、Python、Ruby 等服务器端语言,便于服务器端的解析。
  • 众多服务器端的对象、数组等能够直接生成 JSON 格式,便于客户端的访问提取。
    因为 JSON 格式能够直接为服务器端代码使用,大大简化了服务器端和客户端的代‰ ‰码开发量,但是完成的任务不变,且易于维护。

JSON有两种数据格式

1.1 “名称 / 值”对的集合(A collection of name/value pairs)

“名称 / 值”对的集合形式又称为 JSON Object,其名称和值之间使用“ :”隔开,一般
的形式如下所示:

{name:value}

例如

{ "Width":"800" , "Height":"600" }

其中名称是字符串 ;值可以是字符串、数值、对象、布尔值、有序列表或者 null 值。
字符串是以 “” 括起来的一串字符;数值是一系列 0 ~ 9 的数字组合,可以为负数或者小数,还可以用 e 或者 E 表示为指数形式;布尔值表示为 true 或者 false。

上述是以“{”开始,并以“}”结束的一系列非排序的“名称 / 值”对(每个“名称 /值”对之间使用“,”分隔)。不同的语言中,这种“名称 / 值”可以理解为对象(object)、记录(record)、结构(struct)、字典(dictionary)、哈希表(hash table)、有键列表(keyedlist)或者关联数组(associative array)等。

1.2 值的有序列表(An ordered list of values)

值的有序列表形式又称为 JSON Array。在大部分语言中,值的有序列表被理解为数组
(array),一个或者多个值用“,”分隔后,使用“[”和“]”括起来就形成了这样的列表,
如下所示:

[collection, collection]

例如

{
"employees": [
{ "Width":"800" , "Height":"600" },
{ "Width":"700" , "Height":"800" },
{ "Width":"900" , "Height":"900" }
]
}

二 JSON处理

Android 提供的 JSON 解析类都在包 org.json 下,涉及JSON的解析和打包,主要有以下几个。

  • JSONObject :可以看作是一个 JSON 对象,这是系统中有关 JSON 定义的基本单元,
    前面提到的“名称 / 值”对。
  • JSONStringer :JSON 文本构建类,这个类可以帮助快速和方便地创建 JSON 文本。
    其最大的优点在于可以减少由于格式的错误导致的程序异常,引用这个类可以自动
    严格按照 JSON 语法规则创建 JSON 文本。每个 JSONStringer 实体只能对应创建一
    个 JSON 文本。
  • JSONArray :它代表一组有序的数值。将其转换为 String 输出 (toString) 所表现的形
    式是用方括号包裹,数值以逗号“,”分隔,即前面提到的值的有序列表。
  • JSONTokener:JSON 解析类。
  • JSONException:JSON 中涉及的异常。

2.1 JSON解析

2.1.1 JsonObject解析

JsonObject对象文本如下:

{"name1":"android","name2":"iphone"}

上面 JSON 对象的解析方法如下:

// 新建 JSONObject 对象,将 jsonString 字符串转换为 JSONObject 对象
// jsonString 字符串为上面的文本
JSONObject demoJson = new JSONObject(jsonString);
// 获取名称为 name1 对应的值66 
String name1= demoJson.getString("name1");
// 获取名称为 name2 对应的值
String name2 = demoJson.getString("name2");

2.1.2 JsonArray解析

JsonArray文本如下所示:

{"number":[1,2,3]}

上述JsonArray解析方法如下所示:

// 新建 JSONObject 对象,将 jsonString 字符串转换为 JSONObject 对象
// jsonString 字符串为上面的文本
JSONObject demoJson = new JSONObject(jsonString);
// 获取 number 对应的数组
JSONArray numberList = demoJson.getJSONArray("number");
// 分别获取 numberList 中的每个值
for(int i=0; i<numberList.length(); i++){
// 因为数组中的类型为 int,所以为 getInt,其他 getString、getLong 具有类似的用法
System.out.println(numberList.getInt(i));
}

举例

解析以下JSON文本

{
"query": {
"pages": {
"8325880": {
"pageid": 8325880,
"ns": 0,
"title": "Android",
"revisions": [
{
"*": "{{wiktionary|Android|android}}\n'''Android''' commonly-
refers to:\n* [[Android (robot)]], designed to resemble a human\n* [[Android
(operating system)]], for mobile devices, produced by Google\n'''Android''' may
also refer to:\n* [[Android (board game)|''Android'' (board game)]], published
by Fantasy Flight Games\n* [[Android (drug)]], brand name for the anabolic
steroid methyltestosterone\n* [[Android (film)|''Android'' (film)]], directed by
Aaron Lipstadt\n* [[Android (song)|\"Android\" (song)]], by The Prodigy\n\n==See
also==\n* [[The Androids]], Australian rock band\n* [[Droid (disambiguation)]]\n*
{{Lookfrom}}\n* {{Intitle}}\n\n{{disambiguation}}\n\n[[cs:Android (rozcestník)]]\
n[[de:Android]]\n[[fa:
(
)]]\n[[ko:
]]\n[[id:Android]]\
n[[he:
]]\n[[hu:Android (egyértelm sít
lap)]]\n[[nl:Android]]\n[[ru:
(
)]]\n[[sk:Android (rozlišovacia stránka)]]\n[[sl:Android (razlo itev)]]\
n[[th:
(
)]]\n[[tr:Android]]\n[[uk:
(
)]]\n[[zh-
yue:Android ( 搞清楚 )]]"
}
]
}
}
}
}

解析代码如下所示:

// 从 wiki 服务器获取相关页面信息
protected static synchronized String getUrlContent(String url) throws
ApiException {
// 检测是否设置了 UserAgent 属性
/*User Agent 中文名为用户代理,简称 UA,
UserAgent 是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、
CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等 */
if ( sUserAgent == null ) {
// 抛出自定义异常,提示没有设置 UserAgent 属性
throw new ApiException("User-Agent string must be prepared");
}
// 新建 HttpClient 对象
HttpClient client = new DefaultHttpClient();
// 新建 HttpGet 对象
HttpGet request = new HttpGet(url);
// 添加用户代理
request.setHeader("User-Agent", sUserAgent );
try {
// 打开连接,获取返回信息
HttpResponse response = client.execute(request);
// 检测服务器是否可用
StatusLine status = response.getStatusLine();
// 检测服务器返回的状态码
if (status.getStatusCode() != HTTP_STATUS_OK ) {
// 如果服务状态码返回不正常,这里就抛出自定义异常
throw new ApiException("Invalid response from server: " +
status.toString());
}
// 取回服务器返回的内容
HttpEntity entity = response.getEntity();
// 将返回的内容保存到 InputStream 对象中
InputStream inputStream = entity.getContent();
// 创建 ByteArrayOutputStream 对象
// ByteArrayOutputStream 捕获内存缓存中的数据
// 然后可以将其转换成字节数组或者字符型
ByteArrayOutputStream content = new ByteArrayOutputStream();
int readBytes = 0;
// 将缓存中的数据保存到 ByteArrayOutputStream 对象中
while ((readBytes = inputStream.read( sBuffer )) != -1) {
content.write( sBuffer , 0, readBytes);
}
// 将内容转化为字符串
return new String(content.toByteArray());
} catch (IOException e) {
// 检测到 IO 异常的时候,抛出自定义的异常
throw new ApiException("API 返回错误 ", e);
}
}
// 错误检测,自定义异常
public static class ApiException extends Exception {
// 含有 2 个参数的构造函数
public ApiException(String detailMessage, Throwable throwable) {
super (detailMessage, throwable);
}
// 含有 1 个参数的构造函数
public ApiException(String detailMessage) {
super (detailMessage);
}
}

2.2 JSON打包

要想在客户端通过JSON传送对象, 需要在JSON把信息全部“ 打 包 ” 之 后 将JSONObject转换为String。 这样JSON就会将“ 打 包 ” 的信息按照特定标准的格式进行“压缩”,之后在服务端进行解析,读取通过 JSON 传送来的信息。

用JSON构建以下内容的文本:

{
}
"Strings" : { "Strings1" : "MyStrings", "Strings2" : "MyStrings" },
"Number" : ["987654321", "123456789","456789123"],
"String" : "good",
"Int" : 100,
"Boolean" : false
}

构建代码如下所示:

try {
// 创建 JSONObject 对象
JSONObject mJSONObject = new JSONObject();
// 为 Strings 创建 JSONObject 对象
JSONObject Strings = new JSONObject();
// 为 Strings JSONObject 对象添加第一个“名称 / 值”对
Strings.put("Strings1", " MyStrings");
// 为 Strings JSONObject 对象添加第二个“名称 / 值”对68 
Strings.put("Strings2", " MyStrings");
// 将 Strings 添加到 mJSONObject 中
mJSONObject.put("Strings", Strings);
// 为 Number 创建 JSONArray 对象
JSONArray Number = new JSONArray();
// 将有序列表添加到 Number 中
Number.put("987654321").put("123456789").put("456789123");
// 将 Number 添加到 mJSONObject 中
mJSONObject.put("Number", Number);
// 将 Int“名称 / 值”对添加到 mJSONObject 中
mJSONObject.put("Int", 100);
// 将 Boolean“名称 / 值”对添加到 mJSONObject 中
mJSONObject.put("Boolean", false);
} catch (JSONException ex) {
// 进行异常处理
throw new RuntimeException(ex);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值