当前位置: 首页 > 编程日记 > 正文

使用 jQuery 简化 Ajax 开发

JSON 入门指南

<script language=JavaScript type=text/javascript> </script>

<script language=JavaScript type=text/javascript> </script>


级别: 初级

廖 雪峰, 撰稿人

2008 年 8 月 22 日

JSON 即 JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互。本文将快速讲解 JSON 格式,并通过代码示例演示如何分别在客户端和服务器端进行 JSON 格式数据的处理。

尽管有许多宣传关于 XML 如何拥有跨平台,跨语言的优势,然而,除非应用于 Web Services,否则,在普通的 Web 应用中,开发者经常为 XML 的解析伤透了脑筋,无论是服务器端生成或处理 XML,还是客户端用 JavaScript 解析 XML,都常常导致复杂的代码,极低的开发效率。实际上,对于大多数 Web 应用来说,他们根本不需要复杂的 XML 来传输数据,XML 的扩展性很少具有优势,许多 AJAX 应用甚至直接返回 HTML 片段来构建动态 Web 页面。和返回 XML 并解析它相比,返回 HTML 片段大大降低了系统的复杂性,但同时缺少了一定的灵活性。

现在, JSON 为 Web 应用开发者提供了另一种数据交换格式。让我们来看看 JSON 到底是什么,同 XML 或 HTML 片段相比,JSON 提供了更好的简单性和灵活性。

JSON 数据格式解析

和 XML 一样,JSON 也是基于纯文本的数据格式。由于 JSON 天生是为 JavaScript 准备的,因此,JSON 的数据格式非常简单,您可以用 JSON 传输一个简单的 String,Number,Boolean,也可以传输一个数组,或者一个复杂的 Object 对象。

String,Number 和 Boolean 用 JSON 表示非常简单。例如,用 JSON 表示一个简单的 String “ abc ”,其格式为:

"abc"

除了字符 "// 和一些控制符(/b/f/n/r/t)需要编码外,其他 Unicode 字符可以直接输出。下图是一个 String 的完整表示结构:


图 1. String 的完整表示结构
 图 1. String 的完整表示结构

一个 Number 可以根据整型或浮点数表示如下:


图 2. Number 的表示结构
 图 2. Number 的表示结构

这与绝大多数编程语言的表示方法一致,例如:

12345(整数)
-3.9e10(浮点数)

Boolean 类型表示为 truefalse 。此外,JavaScript 中的 null 被表示为 null,注意,truefalsenull 都没有双引号,否则将被视为一个 String 。

JSON 还可以表示一个数组对象,使用 [] 包含所有元素,每个元素用逗号分隔,元素可以是任意的 Value,例如,以下数组包含了一个 String,Number,Boolean 和一个 null:

["abc",12345,false,null]

Object 对象在 JSON 中是用 {} 包含一系列无序的 Key-Value 键值对表示的,实际上此处的 Object 相当于 Java 中的 Map<String, Object>,而不是 Java 的 Class 。注意 Key 只能用 String 表示。

例如,一个 Address 对象包含如下 Key-Value:

city:Beijing 
street:Chaoyang Road 
postcode:100025(整数)

用 JSON 表示如下:

{"city":"Beijing","street":" Chaoyang Road ","postcode":100025}

其中 Value 也可以是另一个 Object 或者数组,因此,复杂的 Object 可以嵌套表示,例如,一个 Person 对象包含 name 和 address 对象,可以表示如下:

{"name":"Michael","address":
{"city":"Beijing","street":" Chaoyang Road ","postcode":100025}
}

JavaScript 处理 JSON 数据

上面介绍了如何用 JSON 表示数据,接下来,我们还要解决如何在服务器端生成 JSON 格式的数据以便发送到客户端,以及客户端如何使用 JavaScript 处理 JSON 格式的数据。

我们先讨论如何在 Web 页面中用 JavaScript 处理 JSON 数据。我们通过一个简单的 JavaScript 方法就能看到客户端如何将 JSON 数据表示给用户:

function handleJson() { 
var j={"name":"Michael","address":
{"city":"Beijing","street":" Chaoyang Road ","postcode":100025}
}; 
document.write(j.name); 
document.write(j.address.city); 
}

假定服务器返回的 JSON 数据是上文的:

{"name":"Michael","address":
{"city":"Beijing","street":" Chaoyang Road ","postcode":100025}
}

只需将其赋值给一个 JavaScript 变量,就可以立刻使用该变量并更新页面中的信息了,相比 XML 需要从 DOM 中读取各种节点而言,JSON 的使用非常容易。我们需要做的仅仅是发送一个 Ajax 请求,然后将服务器返回的 JSON 数据赋值给一个变量即可。有许多 Ajax 框架早已包含了处理 JSON 数据的能力,例如 Prototype(一个流行的 JavaScript 库:http://prototypejs.org)提供了 evalJSON() 方法,能直接将服务器返回的 JSON 文本变成一个 JavaScript 变量:

new Ajax.Request("http://url", { 
method: "get", 
onSuccess: function(transport) { 
var json = transport.responseText.evalJSON(); 
// TODO: document.write(json.xxx); 
} 
});

服务器端输出 JSON 格式数据

下面我们讨论如何在服务器端输出 JSON 格式的数据。以 Java 为例,我们将演示将一个 Java 对象编码为 JSON 格式的文本。

将 String 对象编码为 JSON 格式时,只需处理好特殊字符即可。另外,必须用 (") 而非 (') 表示字符串:

 
static String string2Json(String s) { 
StringBuilder sb = new StringBuilder(s.length()+20); 
sb.append('/"'); 
for (int i=0; i<s.length(); i++) { 
char c = s.charAt(i); 
switch (c) { 
case '/"': 
sb.append("///""); 
break; 
case '//': 
sb.append(""); 
break; 
case '/': 
sb.append("///"); 
break; 
case '/b': 
sb.append("//b"); 
break; 
case '/f': 
sb.append("//f"); 
break; 
case '/n': 
sb.append("//n"); 
break; 
case '/r': 
sb.append("//r"); 
break; 
case '/t': 
sb.append("//t"); 
break; 
default: 
sb.append(c); 
} 
} 
sb.append('/"'); 
return sb.toString(); 
} 

将 Number 表示为 JSON 就容易得多,利用 Java 的多态,我们可以处理 Integer,Long,Float 等多种 Number 格式:

 
static String number2Json(Number number) { 
return number.toString(); 
} 

Boolean 类型也可以直接通过 toString() 方法得到 JSON 的表示:

 
static String boolean2Json(Boolean bool) { 
return bool.toString(); 
} 

要将数组编码为 JSON 格式,可以通过循环将每一个元素编码出来:

 
static String array2Json(Object[] array) { 
if (array.length==0) 
return "[]"; 
StringBuilder sb = new StringBuilder(array.length << 4); 
sb.append('['); 
for (Object o : array) { 
sb.append(toJson(o)); 
sb.append(','); 
} 
// 将最后添加的 ',' 变为 ']': 
sb.setCharAt(sb.length()-1, ']'); 
return sb.toString(); 
} 

最后,我们需要将 Map<String, Object> 编码为 JSON 格式,因为 JavaScript 的 Object 实际上对应的是 Java 的 Map<String, Object> 。该方法如下:

 
static String map2Json(Map<String, Object> map) { 
if (map.isEmpty()) 
return "{}"; 
StringBuilder sb = new StringBuilder(map.size() << 4); 
sb.append('{'); 
Set<String> keys = map.keySet(); 
for (String key : keys) { 
Object value = map.get(key); 
sb.append('/"'); 
sb.append(key); 
sb.append('/"'); 
sb.append(':'); 
sb.append(toJson(value)); 
sb.append(','); 
} 
// 将最后的 ',' 变为 '}': 
sb.setCharAt(sb.length()-1, '}'); 
return sb.toString(); 
} 

为了统一处理任意的 Java 对象,我们编写一个入口方法 toJson(Object),能够将任意的 Java 对象编码为 JSON 格式:

 
public static String toJson(Object o) { 
if (o==null) 
return "null"; 
if (o instanceof String) 
return string2Json((String)o); 
if (o instanceof Boolean) 
return boolean2Json((Boolean)o); 
if (o instanceof Number) 
return number2Json((Number)o); 
if (o instanceof Map) 
return map2Json((Map<String, Object>)o); 
if (o instanceof Object[]) 
return array2Json((Object[])o); 
throw new RuntimeException("Unsupported type: " + o.getClass().getName()); 
} 

我们并未对 Java 对象作严格的检查。不被支持的对象(例如 List)将直接抛出 RuntimeException 。此外,为了保证输出的 JSON 是有效的,Map<String, Object> 对象的 Key 也不能包含特殊字符。细心的读者可能还会发现循环引用的对象会引发无限递归,例如,精心构造一个循环引用的 Map,就可以检测到 StackOverflowException

 
@Test(expected=StackOverflowError.class) 
public void testRecurrsiveMap2Json() { 
Map<String, Object> map = new HashMap<String, Object>(); 
map.put("key", map); 
JsonUtil.map2Json(map); 
} 

好在服务器处理的 JSON 数据最终都应该转化为简单的 JavaScript 对象,因此,递归引用的可能性很小。

最后,通过 Servlet 或 MVC 框架输出 JSON 时,需要设置正确的 MIME 类型(application/json)和字符编码。假定服务器使用 UTF-8 编码,则可以使用以下代码输出编码后的 JSON 文本:

 
response.setContentType("application/json;charset=UTF-8"); 
response.setCharacterEncoding("UTF-8"); 
PrintWriter pw = response.getWriter(); 
pw.write(JsonUtil.toJson(obj)); 
pw.flush(); 

小结

JSON 已经是 JavaScript 标准的一部分。目前,主流的浏览器对 JSON 支持都非常完善。应用 JSON,我们可以从 XML 的解析中摆脱出来,对那些应用 Ajax 的 Web 2.0 网站来说,JSON 确实是目前最灵活的轻量级方案。

相关文章:

AI一眼识别这是什么鸟 “我们来找茬”十级选手诞生

话说&#xff0c;你能看出这三只鹦鹉有什么不一样吗&#xff1f;脸盲如我&#xff0c;要使出玩“我们来找茬”的十级能力。AWSL&#xff0c;鹦鹉鹦鹉&#xff0c;傻傻分不清楚。结果&#xff0c;AI一顿操作猛如虎&#xff0c;进行了判断&#xff1a;左边的是桃面牡丹鹦鹉&#…

stm32时钟树讲解

1.管理好时钟&#xff0c;功耗才能更低

安全攻防实战:使用winlogonhack获取系统密码

安全攻防实战&#xff1a;使用winlogonhack获取系统密码S.S.F simeon摘要 在网络安全事件频发的今天&#xff0c;很多人都在抱怨&#xff0c;为什么我的系统被入侵了&#xff0c;我的主页被修改了&#xff0c;在入侵后&#xff0c;我采取了一些安全加固措施&#xff0c;可是没…

HTTP长连接服务器端推技术

服务器推送(Server Push) 推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息。服务器发送一批数据&#xff0c;浏览器显示这些数据&#xff0c;同时保证与服务器的连接。当服务器需要再次发送一批数据时&#xff0c;浏览器显示数据并保持连接。以后&#xff0c;…

从AI、加密货币到火星任务,一种更强大、更稳定的存储设备

作者&#xff1a;贺佳来源&#xff1a;数据实战派所研究器件之一的显微镜图像&#xff0c;由两个尺寸相同的十字架组成&#xff0c;其中一个具有 IrMn3 柱&#xff0c;第二个仅由 Pt 组成。&#xff08;来源&#xff1a;西北大学和墨西拿大学&#xff09;美国西北大学和意大利墨…

CSDN - 进程结束后new出的内存会回收吗?

http://blog.csdn.net/stanjiang2010/article/details/5386647 关键词&#xff1a;内存回收

服务器ldap认证配置

1、yum -y install openldap-clients nss-pam-ldapd openldap 2、vim /etc/openldap/ldap.conf进入此配置文件添加如下2行 URI ldap://ldap.shuyun.com:389 BASE dcshuyun,dccom 3、配置自动创建家目录 authconfig --enableldap --enableldapauth --enablemkhomedir --…

使用 .NET 实现 Ajax 长连接

作者&#xff1a;http://www.cnblogs.com/cathsfz/Ajax的长连接&#xff0c;或者有些人所说的Comet&#xff0c;就是指以XMLHttpRequest的方式连接服务器&#xff0c;连接后服务器并非即时写入相应并返回。服务器会保持连接并等待一个需要通知客户端的事件&#xff0c;该事件发…

全员编程时代,人类高质量程序员应具备哪三大特质?

在美国公布的《新兴科技趋势报告》里&#xff0c;2045年&#xff0c;最保守预测也认为将会有超过1千亿的设备连接在互联网上&#xff0c;这些设备包括了移动设备、可穿戴设备、家用电器、医疗设备、工业探测器、监控摄像头、汽车&#xff0c;以及服装等。不久的将来&#xff0c…

[Linux] ubuntu 格式化u盘

$sudo fdisks -l 基本功&#xff0c;格式化命令&#xff0c;以格式化 /dev/sdb4 分区为例&#xff1a; $ sudo umount /dev/sdb4 # 必须先卸载该分区 # 格式化为 FAT 分区 $ sudo mkfs.vfat -F 32 /dev/sdb4 # -F 参数必须大写&#xff0c;参数有 12&#xff0c;16 和…

搭建Mantis 缺陷管理系统(转)

转自 什么是Mantis MantisBT is a free popular web-based bugtracking system (feature list). It is written in the PHP scripting language and works with MySQL, MS SQL, and PostgreSQL databases and a webserver. MantisBT has been installed on Windows, Linux, Mac…

Http环境下的保持连接方式

Http环境本身是一种无连接状态的架构&#xff0c;在这种架构下服务器只能是被动的接受客户端的请求&#xff0c;返回结果&#xff0c;而无法主动的给客户端发送数据。而在很多需要实时数据交互&#xff08;比如Web IM)的场景中&#xff0c;我们却希望能及时得到服务器给我们返回…

22岁专访库克、B站3天涨粉百万,他将毕设树莓派扫描仪升级,繁星散落在校空!...

整理 | 禾木木出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;近日&#xff0c;#何同学毕业#冲上了热搜&#xff0c;4 亿网友阅读词条&#xff0c;1.7 万讨论为他送上毕业祝福&#xff0c;最新毕业视频燃爆朋友圈。过去几个月&#xff0c;要说B站网友苦苦等待的UP主是…

Database Appliance并非Mini版的Exadata-还原真实的Oracle Unbreakable Database Appliance

Oracle甲骨文系统有限公司在北京时间9月23日发布了一款Oracle数据库机即Oracle Database Appliance。Oracle Database Appliance是一款面向中小型企业的使用简单、用得起的高可用数据库专用服务器&#xff0c;该数据库机基于Sun Fire服务器、Oracle Enterprise Linux和Oracle D…

一款基于jquery和css3的响应式二级导航菜单

今天给大家分享一款基于jquery和css3的响应式二级导航菜单&#xff0c;这款导航是传统的基于顶部&#xff0c;鼠标经过的时候显示二级导航&#xff0c;还采用了当前流行的响应式设计。效果图如下&#xff1a; 在线预览 源码下载 实现的代码。 html代码&#xff1a; <div i…

基于PyTorch,如何构建一个简单的神经网络

本文为 PyTorch 官方教程中&#xff1a;如何构建神经网络。基于 PyTorch 专门构建神经网络的子模块 torch.nn 构建一个简单的神经网络。完整教程运行 codelab→https://openbayes.com/console/open-tutorials/containers/OgcYkLjKw89torch.nn 文档→https://pytorch.org/docs/s…

C#语言的几个层次

作者&#xff1a; 李建忠 接到一位前不久C#培训学员的来信&#xff0c;这位学员虽然以前功底欠缺&#xff0c;但学习劲头很足&#xff0c;在培训中成长很快。即便基本吃透《.NET框架&#xff08;修订版&#xff09;》还嫌不够过瘾&#xff0c;一心要成为高手中的高手。来信的目…

确定安全威胁与漏洞-A

1、社会工程学攻击是一种使用欺骗和诡计说服不知情的用户提供敏感信息或做出违背安全准则行为的攻击类型。通常通过人、电子邮件、电话等方式表现出来。 2、社会工程学攻击类型主要有电子欺骗、冒名顶替、骗局、网络钓鱼、电话钓鱼、大型网络钓鱼&#xff08;鱼叉式网络钓鱼&am…

C# 特性(Attribute)学习。

特性&#xff08;attribute&#xff09;是被指定给某一声明的一则附加的声明性信息。 在C#中&#xff0c;有一个小的预定义特性集合。在学习如何建立我们自己的定制特性&#xff08;custom attributes&#xff09;之前&#xff0c;我们先来看看在我们的代码中如何使用预定义特性…

JMeter学习(二十三)关联

话说LoadRunner有的一些功能&#xff0c;比如&#xff1a;参数化、检查点、集合点、关联&#xff0c;Jmeter也都有这些功能&#xff0c;只是功能可能稍弱一些&#xff0c;今天就关联来讲解一下。 JMeter的关联方法有两种&#xff1a;后置处理器&#xff0d;正则表达式提取器与X…

程序员千万不要选全栈开发

作者 | 千鸟&#xff08;网名&#xff09; 小路助手开发者责编 | 晋兆雨出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;对于大多数人来说&#xff0c;大学毕业后选择一家满意的公司&#xff0c;一路升职加薪才是正解&#xff0c;但他却偏偏选择了一条鲜有人知的…

手动初始化设置3PAR存储系统

准备工作 1. 具备串口的终端电脑&#xff08;USB to serial&#xff09;. 2. 使用标记为“180-055”灰色适配器(3par自带). 3. 标准RJ45网线. 4. 下载HP 3par OS及SP Patch包. 5. PuTTY软件&#xff08;或其他串口软件&#xff09; 其他说明 手动设置存储系统&#xf…

C# 里怎样得到当前执行的函数名,当前代码行,源代码文件名。

得到函数名&#xff1a; System.Diagnostics.StackTrace st new System.Diagnostics.StackTrace(); this.Text st.GetFrame(0).ToString(); 得到代码行&#xff0c;源代码文件名&#xff1a; StackTrace st new StackTrace(new StackFrame(true));Consol…

特斯拉Model 3国内起售价下调至23.59万元

7月30日11:00&#xff0c;特斯拉官方微博宣布&#xff0c;即日起&#xff0c;特斯拉Model 3标准续航升级版的价格下调15000元人民币&#xff0c;调整后的价格为235900元人民币&#xff08;此为补贴后起售价&#xff09;。此次价格调整反映了成本波动的实际情况。特斯拉一直秉承…

Maven内置变量

1、Maven内置变量说明&#xff1a; ${basedir} 项目根目录${project.build.directory} 构建目录&#xff0c;缺省为target${project.build.outputDirectory} 构建过程输出目录&#xff0c;缺省为target/classes${project.build.finalName} 产出物名称&#xff0c;缺省为${proje…

在客户端调用MOSS的搜索服务,实现更加灵活的搜索控制

MOSS中提供了很多web services的服务&#xff0c;都放在http://<Site>/_vti_bin下 我们可以在其他地方&#xff0c;比如winForm&#xff0c;webForm中调用&#xff0c;对MOSS的对象进行灵活操作。 下面我简单列一下调用一个MOSS中的搜索服务的方法&#xff1a; 1、在VS…

年收入百万美元AI科学家的烦恼与思考

AI 研究科学家 Alexis Conneau 只需敲击了几下键盘&#xff0c;包含数千亿字的信息洪流&#xff0c;就能在他的电脑屏幕窗口中滚动起来。多年来&#xff0c;自动化 “爬虫” 用 100 种语言将互联网中的古老诗歌、愤怒的评论、甜点食谱和其他一切信息吸进庞大的数据库中。作为人…

web架构设计经验分享

本人作为一位web工程师&#xff0c;着眼最多之处莫过于 性能与架构&#xff0c;本次幸得参与sd2.0大会&#xff0c;得以与同行广泛交流,于此二方面&#xff0c;有些心得&#xff0c;不敢独享&#xff0c;与众博友分享&#xff0c;本文是这次参会与众同撩交流的心得&#xff0c;…

BOM和DOM的区别

为什么80%的码农都做不了架构师&#xff1f;>>> BOM 浏览器对象模型提 供了独立于内容而与浏览器窗口进行交互的对象。描述了与浏览器进行交互的方法和接口&#xff0c;可以对浏览器窗口进行访问和操作&#xff0c;譬如可以弹出新的窗口&#xff0c;改变状态栏 中的…

C#编码简单性之语义篇(如何编写简短的C#代码,随时更新)

以前写C的时候曾经在自己网站上发表过一个编码“简单性”之文章&#xff0c;现在编写C#了才发现自己无意之间就会写下一些浪费屏幕的代码。下面是自己编码中偶然发现的一些案例&#xff0c;欢迎中等水平的编程者参考。因为要积累案例&#xff0c;所以随时更新。---------------…