4.2 负载

负载指的是在服务的请求响应事务中交换的数据。 比如, 在 POST 请求中, 负载指的就是请求体。 负载并不包含其他数据, 如请求头或是请求的 HTTP 方法, 例如 POST。 如果应用要向 Web Service 发送消息或是接收来自于 Web Service 的信息, 那么你需要清楚地理解请求与响应的负载格式

4.2.1 负载数据格式简介

进入与发出的负载数据存在很多形式与大小。 比如, 有些开发者会使用原生的字符串或是以分隔符分开的数据与 Web Service 进行通信。这么做虽然简单, 不过技术上却不具备可扩展性, 难以处理复杂的数据结构, 可能会导致很多问题。 本节将会介绍用于发送和接收结构化数据的 3 种标准方式, 分别是可扩展标记语言(XML)、JavaScript 对象符号(JSON)以及超文本标记语言(HTML)。

1. XML

XML 是一种标记语言, 用于编码和组织数据。 XML 规范(标准通用标记语言 SGML 的扩展) 开始于 1996 年, 由万维网联盟(W3C)制订。 第 5 次修订于 2008 年 11 月发布。 最初, XML 的关注点在于文档, 不过现在已经被广泛用作 Web Service 中传递结构化数据的格式。 XML 已经被扩展为很多标记语言和协议, 比如用于组织声音参数控制的 VoiceXML、用于交换财务数据的 Open Financial Exchange(OFX) 以及用于发布媒体内容的 Really Simple Syndication(RSS)等。 上一节曾提到过, SOAP 协议也通过 XML 来交换结构化数据。

XML 文档包含标记与内容、标记由标签、属性与元素构成。 有 3 种类型的标签: 起始标签(<person>)、结束标签(</person>)以及空元素标签(<noContact />)。 空元素标签也叫做自关闭标签。 属性指的是起始标签或空元素标签中的键值对, 它们提供了关于元素的附加信息.

元素指的是构成 XML 文档的组件. 元素是标签、属性与内容的集合. 元素包含起始标签与结束标签或是空元素标签. 起始标签与结束标签之间的数据就是内容. 内容可以包含标记与其他元素, 这样就可以在数据结构中构建父子关系了. 下述代码片段展示了一个 XML 元素示例:
<person>
     <firstName>Nathan</firstName>
     <lastName>Jones</lastName>
     <emailAddress primary = 'true'>email@domain.com</emailAddress>
     <noContace medium = 'email' />
</person>

上述代码描述了一个名为 person 的元素, 该元素包含几个子元素: firstName、lastName、emailAddress 与 noContact. emailAddress 元素包含一个属性, 用于表明该元素的内容是这个人的主 E-Mail 地址. noContact 元素 (表示这个人不想被联系) 也包含了一个属性, 用于表明不应该通过哪种方式联系这个人

2. JSON

JSON 是一种用于交换结构化信息的轻量级数据格式. 

JSON 拥有小巧的格式规则定义集合, 在创建负载时需要严格遵守. 下面是 JSON 支持的数据类型以及与之关联的格式规则:
- 数字: 无双引号
- 布尔: 取值为 true 或 false, 无双引号
- 字符串: 双引号括起
- 数组: 方括号包围的以逗号分隔的列表
- 对象: 花括号的键值对集合. Objective-C 中的对象是通过 NSDictionary 表示的
- null: 无双引号

格式良好的 JSON 文档的根类型要么是数组, 要么是对象. 如下代码片段使用 JSON 表示之前用 XML 表示的 person 示例:
{
    "person": {
        "firstName": "Nathan",
        "lastName": "Jones",
        "email": {
            "emailAddress": "email@domain.com",
            "primary": true
        },
        "noContact": "email"
    }
}

3. HTML

HTML 是一种标记语言, 用于组织网页上的数据, 这样浏览器就可以解析页面了.

HTML 文档结构类似于 XML 文档, 它们都起源于 SGML. 然而, HTML 新的草案(HTML5) 并不像之前的版本那样基于 SGML. HTML 文档包含 doctype 定义(DTD)、元素、属性、数据类型与字符实体引用. HTML 与 XML 文档结构的主要差别在于 HTML 文档拥有预先定义好的标签与属性名的集合

doctype 定义位于 HTML 文档的第一行, 它告诉浏览器当前页面使用的是 HTML 规范的哪个版本. 元素的属性是位于起始标签中的键值对. 不过 HTML5 还支持自定义属性. 这些属性以 data- 作为前缀, 并且不应该包含大写字母. 自定义属性旨在存储不适合现有属性存储的特定于应用的数据. 


HTML 示例

4.2.2 解析响应负载

1. XML

SAX 解析器是事件驱动的, 它会顺序解析 XML 文档中的元素, 一次处理一个元素.
DOM 解析器则会将整个 XML 文档以可遍历的结点树的形式读取到内存中.

iOS 自带了两种原生 XML 解析器, 分别是 NSXMLParserlibxml. NSXMLParser 是个 Objective-C SAX 解析器, 在遇到元素、属性、CData 块、注释与文档起始和结束事件时会调用各种委托方法. libxml 是个开源、基于 C 语言的 API , 支持 SAX 与 DOM 解析. libxml SAX 解析类似于 NSXMLParser, 因为在遇到某些事件时会进行大量回调. libxml DOM 会将整个 XML 文档读取为结点树, 可以通过 XML Path Language(XPath) 遍历与查询. 这里的示例使用了 NSXMLParser, 不过在稍后解析 HTML 时会使用 libxml.


第三方 XML 库

在决定选择解析器时, 预期的 XML 文档大小是个重要的考虑因素:

NSXMLParser 委托:
- parserDidStartDocument: 解析器开始解析 XML 种子时调用
- parserDidEndDocument: 解析器到达文档末尾时调用
- parser:didStartElement:namespaceURI:qualifiedName:attributes: 开始处理新元素时调用 
- parser:foundCharacters: 当从元素中读取内容时调用 
- parser:didEndElement:namespaceURI:qualifiedName: 当元素关闭时调用

2. HTML

HTML 文档的结构类似于 XML. 不过, XML 文档的结构要求发送端与接收端遵循某种服务契约. 

考虑到 HTML 文档很容易变化这个问题, 你不应该在应用中解析 HTML, 变更会极大地影响应用的正常使用

3. JSON

NSJSONSerialization 的 options 参数
- NSJSONReadingAllowFragments: 告诉解析器处理既不是 NSArray 也不是 NSDictionary 的顶层对象. 这个选项可以处理诸如 {"user": null} 这样的简单 JSON 结构的转换
- NSJSONReadingMutableContainers: 告诉解析器生成 NSMutableArray 与 NSMutableDictionary 对象. 可变对象意味着可以通过方法修改它们, 比如 NSMutableArray 的 addObject: 与 NSMutableDictionary 的 setObject:forKey:. 这可以用于如下场景: 有主要和次要的结果集, 你要在进一步处理前将次要结果中的值添加到主要结果中.
-NSJSONReadingMutableLeaves: 告诉解析器生成 NSMutableString 对象. 如果要在进一步处理前操纵被解析的响应中的某个特定值, 那么可以使用该选项.

4.2.3 生成请求负载

1. JSON

NSJSONSerialization 还提供了 isValidJSONObject: 来验证尝试转换的 Foundation 对象是否可以转换成 JSON. 对于能够转换为 JSON 的对象来说, 必须满足如下规则:
- 顶层对象是 NSArray 或 NSDictionary
- 所有的对象必须是 NSString、NSNumber、NSArray、NSDictionary 或 NSNull
- 所有的 NSDictionary 键必须是 NSStrings
- NSNumbers 不能为 NaN 或无穷大

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,745评论 6 342
  • 你说人生最美妙的风景在脚下 我怔怔地看着脚下 ...
    刘一在阅读 753评论 2 3
  • 本以为自己不会再去想任何的事,可是自己还是在无行中会去想很多的事。一场漫雨,一声笑语,一片落叶都会把人带入想象的世...
    牛赋阅读 382评论 0 3
  • 乐观随和的外向性格,容易接触却不容易亲近; 她们大多善良和真诚;相信爱与美好; 不拒绝外界对其伸出的友好与善意; ...
    雁无蝉阅读 1,178评论 1 3