网络数据交换格式

Deadly 提交于 2019-11-29 06:03:11

                                             1.Json的讲解

1.1json是什么?

•JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。

JSON采用兼容性很高的、完全独立于语言文本格式,同时也具备类似于C语言的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)体系的行为。这些特性使JSON成为理想的数据交换语言。

•本质就是具有特定格式的字符串

•JSON数据已经是客户端与服务器端交互的最常用的选择, 已经很少使用xml来进行数据交互了

1.2json的数据格式

•整体结构:

•Json数组 :  [ ]

•Json对象: {  }

•Json数组的结构: [value1, value2, value3]

•Json对象的结构: {key1:value1, key2:value2, key3:value3}

•key的数据类型: 字符串

•value的数据类型:

•数值

•字符串

•null

•json数组 []

•json对象 {}

•例子:

      [1, “ab”,[], {“n”:123, “b”:”abc”}]       [1, “a”:3]
          {“name”:”TOM”, “age”:12}      {“aa”:“a”, 3}

2.1json的解析

解析技术:

•Android原生API : 编程相对麻烦

•Gson框架 : 编码简洁, 项目首选

解析方向:

•将java对象(包含集合)转换为json格式字符串(服务器)

将json格式字符串转换为java对象(包含集合)

2.2相关的api

•Android原生API:

•JsonObject : json对象   { }

•JSONObject(String json) : 将json字符串解析为json对象

•Xxx getXxx(String name) : 根据name, 在json对象中得到对应的Value

•JsonArray : json数组   []

•JSONArray(String json) : 将json字符串解析为json数组

•int length() : 得到json数组中元素的个数

•Xxx getXxx(int index) : 根据下标得到json数组中对应的元素数据

•Gson框架API

•Gson : 能解析json数据的类

•Gson() : 构造对象的方法

•String toJson(Object src) : 将对象转换为对应格式的json字符串

•T fromJson(String json, Type typeOfT) : 解析Json字符串, 得到对象

•TypeToken<T> : 用来得到Type的类

•protected TypeToken() : 受保存的构造方法

•Type getType() : 得到类型对象

3.测试数据

测试解析{ }
{
	"id":2, "name":"大虾", 
	"price":12.3, 
	"imagePath":"http://192.168.10.165:8080/L05_Server/images/f1.jpg"
}
测试解析[ ]
[
	{
	"id":1, "name":"大虾1", 
	"price":12.3, 
	"imagePath":"http://192.168.10.165:8080/f1.jpg"
},
{
	"id":2, "name":"大虾2", 
	"price":12.5, 
	"imagePath":"http://192.168.10.165:8080/f2.jpg"
}
]

4.测试案例

4.1实体类ShopInfo的代码:

public class ShopInfo {

	private int id;
	private String name;
	private double price;
	private String imagePath;

	public ShopInfo(int id, String name, double price, String imagePath) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
		this.imagePath = imagePath;
	}

	public ShopInfo() {
		super();
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public String getImagePath() {
		return imagePath;
	}

	public void setImagePath(String imagePath) {
		this.imagePath = imagePath;
	}

	@Override
	public String toString() {
		return "ShopInfo [id=" + id + ", name=" + name + ", price=" + price
				+ ", imagePath=" + imagePath + "]";
	}

}

4.2测试类JsonTest 的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.test.AndroidTestCase;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/*
1. 将json格式的字符串{}转换为Java对象, 使用原生API
2. 将json格式的字符串{}转换为Java对象, 使用GSON
3. 将json格式的字符串[]转换为Java对象的List, 使用原生API
4. 将json格式的字符串[]转换为Java对象的List, 使用GSON

5. 将Java对象转换为json字符串{}, 使用GSON
6. 将Java对象的List转换为json字符串[], 使用GSON
 */
public class JsonTest extends AndroidTestCase{

	/*
	 * 1. 将json格式的字符串{}转换为Java对象, 使用原生API
	 */
	public void testJsonToObject() throws JSONException {
		String jsonString = "{\"id\":2, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"}";
		
		//将json字符串封装为JSONObject对象
		JSONObject jsonObject = new JSONObject(jsonString);
		//从对象中根据key得到对应的value
		int id = jsonObject.getInt("id");
		String name = jsonObject.getString("name");
		double price = jsonObject.getDouble("price");
		String imagePath = jsonObject.getString("imagePath");
		//封装ShopInfo对象
		ShopInfo shopInfo = new ShopInfo(id, name, price, imagePath);
		
		Log.e("TAG", shopInfo.toString());
	}
	
	/*
	 * 1. 将json格式的字符串{}转换为Java对象, 使用GSON
	 */
	public void testJsonToObject2()  {
		String jsonString = "{\"id\":3, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"}";
		
		ShopInfo shopInfo = new Gson().fromJson(jsonString, ShopInfo.class);
		
		Log.e("TAG", shopInfo.toString());
	}
	
	
	/*
	 * 3. 将json格式的字符串[]转换为Java对象的List, 使用原生API
	 */
	public void testJsonToList() throws JSONException {
		String jsonString = "[{\"id\":3, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"},"
				+ "{\"id\":5, \"name\":\"大虾2\", \"price\":128.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f2.jpg\"}]";
		List<ShopInfo> list = new ArrayList<ShopInfo>();
		
		//1. 将json字符串包装JSONArray对象
		JSONArray jsonArray = new JSONArray(jsonString);
		//2. 遍历JSONArray对象所有元素(JSONObject), 并将每个元素封装为shopInfo, 并添加到List
		for(int i=0;i<jsonArray.length();i++) {
			JSONObject jsonObject = jsonArray.getJSONObject(i);
			//从对象中根据key得到对应的value
			int id = jsonObject.getInt("id");
			String name = jsonObject.getString("name");
			double price = jsonObject.getDouble("price");
			String imagePath = jsonObject.getString("imagePath");
			//封装ShopInfo对象
			ShopInfo shopInfo = new ShopInfo(id, name, price, imagePath);
			list.add(shopInfo);
		}
		
		Log.e("TAG", list.toString());
	}
	
	/*
	 * 4. 将json格式的字符串[]转换为Java对象的List, 使用GSON
	 */
	public void testJsonToList2() throws JSONException {
		String jsonString = "[{\"id\":4, \"name\":\"大虾\", \"price\":12.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"},"
				+ "{\"id\":6, \"name\":\"大虾2\", \"price\":128.3,\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f2.jpg\"}]";
		
		List<ShopInfo> list = new Gson().fromJson(jsonString, new TypeToken<List<ShopInfo>>(){}.getType());
		
		Log.e("TAG", list.toString());
	}
	
	/*
		5. 将Java对象转换为json字符串{}, 使用GSON
	*/
	public void testObjectToJson() {
		ShopInfo info = new ShopInfo(3, "KK", 1000, "http://www.sina.com");
		String json = new Gson().toJson(info);
		Log.e("TAG", json);
	}
	
	
	/*
		6. 将Java对象的List转换为json字符串[], 使用GSON
	*/
	
	public void testListToJson() {
		
		List<ShopInfo> list = new ArrayList<ShopInfo>();
		list.add(new ShopInfo(3, "KK", 1000, "http://www.sina.com"));
		list.add(new ShopInfo(4, "KK2", 2000, "http://www.sina.com222"));
		
		String json = new Gson().toJson(list);
		
		Log.e("TAG", json);
	}
	
	public void testJsonToMap() {
		String jsonString = "{\"my name\":\"大虾\", \"1\":12}";
		Map<String, Object> map = new Gson().fromJson(jsonString, new TypeToken<Map<String, Object>>(){}.getType());
		Log.e("TAG", map.toString());
	}
}

                                     2.XML数据讲解

XML定义

扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML使用DTD(document type definition)文档类型定义来组织数据;格式统一,跨平台和语言,早已成为业界公认的标准。XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

 在Android中,常见的XML解析器分别为SAX解析器、DOM解析器和PULL解析器,下面,我给大家做详细的介绍。

1.SAX解析器:

SAX(Simple API for XML)解析器是一种基于事件的解析器,它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。
总结:SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。

2. DOM解析器:

 DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。

总结: 由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。

3. PULL解析器:

PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中,我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器。
总结: 在Android中,首推当然就是pull解析器了。PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术。Pull解析技术是第三方开发的开源技术,它同样可以应用于JavaSE开发。
3.1 PULL 的工作原理:

 XML pull提供了开始元素和结束元素。当某个元素开始时,可以调用parser.nextText从XML文档中提取所有字符数据。当解析到一个文档结束时,自动生成EndDocument事件。

常用的XML pull的接口和类:

XmlPullParser:该解析器是一个在org.xmlpull.v1中定义的解析功能的接口。

XmlSerializer:它是一个接口,定义了XML信息集的序列。

XmlPullParserFactory:这个类用于在XMPULL V1 API中创建XML Pull解析器。

XmlPullParserException:抛出单一的XML pull解析器相关的错误。

 PULL解析器的运行方式和SAX类似,都是基于事件的模式。

不同的是,在PULL解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码: 

读取到xml的声明返回 START_DOCUMENT;

结束返回 END_DOCUMENT ;

开始标签返回 START_TAG; 

结束标签返回 END_TAG;

文本返回 TEXT。

4.最后对这3个解析技术做个比较与总结:

  1. 对于Android的移动设备而言,因为设备的资源比较宝贵,内存是有限的,所以我们需要选择适合的技术来解析XML,这样有利于提高访问的速度。

  2.   DOM在处理XML文件时,将XML文件解析成树状结构并放入内存中进行处理。当XML文件较小时,我们可以选DOM,因为它简单、直观。

  3. SAX则是以事件作为解析XML文件的模式,它将XML文件转化成一系列的事件,由不同的事件处理器来决定如何处理。XML文件较大时,选择SAX技术是比较合理的。虽然代码量有些大,但是它不需要将所有的XML文件加载到内存中。这样对于有限的Android内存更有效,而且Android提供了一种传统的SAX使用方法以及一个便捷的SAX包装器。 使用Xml类,会比使用 SAX来得简单。

  4.    XML pull解析并未像SAX解析那样监听元素的结束,而是在开始处完成了大部分处理。这有利于提早读取XML文件,可以极大的减少解析时间,这种优化对于连接速度较漫的移动设备而言尤为重要。对于XML文档较大但只需要文档的一部分时,XML Pull解析器则是更为有效的方法。

        参考的文章www.moliying.com

                               3.XML与JSON的对比

1.XML和JSON优缺点:

1.1XML的优缺点:

<1>.XML的优点

A.格式统一,符合标准;

B.容易与其他系统进行远程交互,数据共享比较方便。

<2>.XML的缺点

A.XML文件庞大,文件格式复杂,传输占带宽;

B.服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;

C.客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;

D.服务器端和客户端解析XML花费较多的资源和时间。

1.2JSON的优缺点:

<1>.JSON的优点:

A.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;

B.易于解析,客户端JavaScript可以简单的通过eval()进行JSON数据的读取;

C.支持多种语言,包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服务器端语言,便于服务器端的解析;

D.在PHP世界,已经有PHP-JSON和JSON-PHP出现了,偏于PHP序列化后的程序直接调用,PHP服务器端的对象、数组等能直接生成JSON格式,便于客户端的访问提取;

E.因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。

<2>.JSON的缺点

A.没有XML格式这么推广的深入人心和喜用广泛,没有XML那么通用性;

B.JSON格式目前在Web Service中推广还属于初级阶段。

2、XML和JSON的优缺点对比:

(1).可读性方面。

JSON和XML的数据可读性基本相同,JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,XML可读性较好些。

(2).可扩展性方面。

XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。

(3).编码难度方面。

XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。

(4).解码难度方面。

XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。

(5).流行度方面。

XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous Javascript and JSON)了。

(6).解析手段方面。

JSON和XML同样拥有丰富的解析手段。

(7).数据体积方面。

JSON相对于XML来讲,数据的体积小,传递的速度更快些。

(8).数据交互方面。

JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。

(9).数据描述方面。

JSON对数据的描述性比XML较差。

(10).传输速度方面。

JSON的速度要远远快于XML。

3.XML与JSON数据格式比较:

(1).关于轻量级和重量级

轻量级和重量级是相对来说的,那么XML相对于JSON的重量级体现在哪呢?应该体现在解析上,XML目前设计了两种解析方式:DOM和 SAX。

<1>.DOM

DOM是把一个数据交换格式XML看成一个DOM对象,需要把XML文件整个读入内存,这一点上JSON和XML的原理是一样的,但是XML要考虑父节点和子节点,这一点上JSON的解析难度要小很多,因为JSON构建于两种结构:key/value,键值对的集合;值的有序集合,可理解为数组;

<2>.SAX

SAX不需要整个读入文档就可以对解析出的内容进行处理,是一种逐步解析的方法。程序也可以随时终止解析。这样,一个大的文档就可以逐步的、一点一点的展现出来,所以SAX适合于大规模的解析。这一点,JSON目前是做不到得。

所以,JSON和XML的轻/重量级的区别在于:

JSON只提供整体解析方案,而这种方法只在解析较少的数据时才能起到良好的效果;

XML提供了对大规模数据的逐步解析方案,这种方案很适合于对大量数据的处理。

(2).关于数据格式编码及解析难度

<1>.在编码方面。

虽然XML和JSON都有各自的编码工具,但是JSON的编码要比XML简单,即使不借助工具,也可以写出JSON代码,但要写出好的XML代码就有点困难;与XML一样,JSON也是基于文本的,且它们都使用Unicode编码,且其与数据交换格式XML一样具有可读性。

主观上来看,JSON更为清晰且冗余更少些。JSON网站提供了对JSON语法的严格描述,只是描述较简短。从总体来看,XML比较适合于标记文档,而JSON却更适于进行数据交换处理。

<2>.在解析方面。

在普通的web应用领域,开发者经常为XML的解析伤脑筋,无论是服务器端生成或处理XML,还是客户端用 JavaScript 解析XML,都常常导致复杂的代码,极低的开发效率。

实际上,对于大多数Web应用来说,他们根本不需要复杂的XML来传输数据,XML宣称的扩展性在此就很少具有优势,许多Ajax应用甚至直接返回HTML片段来构建动态Web页面。和返回XML并解析它相比,返回HTML片段大大降低了系统的复杂性,但同时缺少了一定的灵活性。同XML或 HTML片段相比,数据交换格式JSON 提供了更好的简单性和灵活性。在Web Serivice应用中,至少就目前来说XML仍有不可动摇的地位。

4.、实例比较

XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较

<1>.用XML表示中国部分省市数据如下:

<2>.用JSON表示中国部分省市数据如下:

 

 

 

 

 

 

 

 

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!