Android中Json数据解析(一)--Json初步

转载请注明出处:http://blog.csdn.net/yegongheng/article/details/38259139


Json的定义

       Json,JavaScript Object Notation的缩写,是一种轻量级的数据交换格式,它是基于JavaScript (Standard ECMA-262 3rd Edition - December 1999)的一个子集,目前大多数的语言平台都支持Json的解析(C、C++、Java和C#等等),而且Json采用了完全独立于语言的文本格式,因此使用Json数据解析可以在不同的平台进行数据交换。那么Json有哪些特点呢?下面我简单总结了一下:
       (1)具有良好的可读性;
       (2)易于机器快速解析和生成;
       (3)便于开发人员快速编写;
       (4)拥有丰富的解析手段
       (5)相比于其它数据解析方式(比如XML解析),数据的体积更小
Json的优点颇多,自然很多平台系统都支持Json数据的交换和解析,特别是对于使用内存资源有限的手持设备系统(Android和IOS)来讲,Json无疑是一个非常好的选择。目前主流的手机系统Android和IOS都对Json解析提供了完整的解决方案,并且由于Json数据及解析具有良好的可读和便于快速编写的特点,其受到了很多开发者的青睐,市面上很多具有网络交互功能的APP都使用了Json进行数据解析和交换。
       初步了解了Json的特点后,我们来见识一下什么是Json数据以及Json数据的表现形式是怎样的。
       什么是Json数据?Json数据其实就是一连串字符数据以某种特定的组织形式组成的数据,而我们再根据其特点使用相应的解析方式对其进行解析成具体的对象,这就是所谓的Json解析。那么Json数据到底有哪些组织形式呢?一般的,Json数据包括两种组织结构形式:
       (1)以键值对(key/value)形式存在的无序的jsonObject对象,一个对象以“{”(左花括号)开始,“}”(右花括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔,如图下:

Android中Json数据解析(一)--Json初步_第1张图片
对于该种格式,其中key的值必须是String类型,String类型的值是使用" "号包含的,它可以包括任意长度的字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string),如图下:

Android中Json数据解析(一)--Json初步_第2张图片

而对于value,则可以是String、Object、number和Array等等,如图下:
Android中Json数据解析(一)--Json初步_第3张图片
例如{"name":"AndroidLeaf"}就是一个简单的Json对象,其组织形式是{String:String},而又比如{“person”:["AndroidLeaf","Steve.P.Jobs","Bill Gates"]}也是一个Json对象,其组织形式是{String:Array}。
      (2)Json另一种数据组织就是有序的value的集合,这种形式被称为是jsonArray,数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。如下图:

Android中Json数据解析(一)--Json初步_第4张图片
同样的,value也可以是String、Object、number和Array等等。例如["AndroidLeaf","Steve.P.Jobs","Bill Gates"]就是一个数组集合,其组织形式是[String]。
Json的这两种数据组织结构形式在实际开发当中,在组织数据时,可以相互、多层嵌套,这样我们可以利用其灵活的特点将我们所需要的数据组成我们所需要的数据格式,进而满足开发需求。该知识点非常重要,读者需要深入理解并灵活地使用 这两种数据结构形式。
想了解更多有关Json的知识,可以查看官网的学习资料:www.json.org。
Android中Json数据解析实例
      初步了解了Json的概念和特点后,我们应该学习如何使用Json技术进行数据解析了,Android系统本身内置了Json原生态类库供我们使用,下图是Android中解析Json数据所提供的几个关键类,如下图:
Android中Json数据解析(一)--Json初步_第5张图片
我们来一一了解一下这几个类的主要作用:

JSONObject:JSONObject是一个名称/值对的集合。它主要就是为了操作我们上面介绍的Json两种数据组织结构形式中的第一种,以键值对(key/value)形式存在的无序的jsonObject对象。该类的作用主要包括:可以用JSONObject.put(String key,Object object)方法将Java对象转换成Json字符串;还有就是可以用JSONObject.get(String key)方法将Json字符串转换成对应的Java对象。实际上一句话总结就是JSONObject可以实现Java对象和Json字符串之间的相互转换。

JSONArray: JSONArray是一个有序序列值的集合。它主要就是为了操作我们上介绍的第二种数据组织结构形式。该类的主要作用也是可以用JSONArray.put(Object object)方法和JSONArray.get...(Object object)方法实现Java对象集合和Json字符串之间的相互转换。

JSONStringer:JSONStringer是一个JSON文本构建类 ,根据官方的解释,这个类可以帮助快速和便捷的创建JSON text。其最大的优点在于可以减少由于 格式的错误导致程序异常,引用这个类可以自动严格按照JSON语法规则(syntax rules)创建JSON text。每个JSONStringer实体只能对应创建一个JSON text。

JSONTokener:JSONTokener是一个Json字符串的解析类,它主要的作用就是读取一个Json字符串里面的字符,比如读取Json字符串中的指定位置的字符、读取下一个字符、读取上一个字符、跳转到指定位置的字符等等。

JSONException:JSON异常处理类。
下面我们通过一个小示例来具体了解一下上面这几个类在实际编程中的使用方法,我创建一个Java工程08_Json_Test_Blog,然后工程代码列表如下:
Android中Json数据解析(一)--Json初步_第6张图片
(记得导入json.jar包,jar包百度搜就可以)
其中代码列表中Person.java是一个Entity类,再此不列出代码,而主要代码文件是JsonTest.java,其具体的代码如下:
/**
 * Json中JSONObject、JSONArray、JSONStringer和JSONTokener的使用实例
 * @author AndroidLeaf
 *
 */
public class JsonTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JsonTest mJsonTest = new JsonTest();
		//mJsonTest.jsonObjectTest();
		//mJsonTest.jsonArrayTest();
		//mJsonTest.jsonStringTest();
		mJsonTest.jsonTokenerTest();
	}
	
	/**
	 * JsonObject对象的使用
	 */
	public void jsonObjectTest(){
		Person mPerson = testDataPerson();
		
		/**
		 * 将Person对象转换成Json字符串
		 */
		JSONObject mJsonObject = new JSONObject();
		try {
			//添加值到mJsonObject对象中
			mJsonObject.put("id", mPerson.getId());
			mJsonObject.put("userName", mPerson.getUserName());
			mJsonObject.put("password", mPerson.getPassword());
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(mJsonObject.toString());
		/**打印的内容为:{"id":1,"userName":"AndroidLeaf","password":"123"} */
		
		/**
		 * 将Json字符串转换成对应的Person对象
		 */
		Person mPerson2 = new Person();
		JSONObject mJsonObject2;
		try {
			 mJsonObject2 = new JSONObject(mJsonObject.toString());
			 mPerson2.setId(mJsonObject2.getInt("id"));
			 mPerson2.setUserName(mJsonObject2.getString("userName"));
			 mPerson2.setPassword(mJsonObject2.getString("password"));
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(mPerson2.toString());
		/**打印的内容为:Person [id=1, userName=AndroidLeaf, password=123]*/
	}
	
	/**
	 * JsonArray对象的使用
	 */
	public void jsonArrayTest(){
		
		ArrayList mList = testDataPersons();
		/**
		 * 将Person集合对象转换成Json字符串
		 */
		JSONArray mJsonArray = new JSONArray();
		for(int i = 0; i < mList.size();i++){
			Person mPerson = mList.get(i);
			try{
				JSONObject mJsonObject = new JSONObject();
				mJsonObject.put("id", mPerson.getId());
				mJsonObject.put("userName", mPerson.getUserName());
				mJsonObject.put("password", mPerson.getPassword());
				mJsonArray.put(mJsonObject);
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(mJsonArray.toString());
		/**打印的内容为:[{"id":0,"userName":"AndroidLeaf 0","password":"1230"},
		 * {"id":1,"userName":"AndroidLeaf 1","password":"1231"},
		 * {"id":2,"userName":"AndroidLeaf 2","password":"1232"},
		 * {"id":3,"userName":"AndroidLeaf 3","password":"1233"},
		 * {"id":4,"userName":"AndroidLeaf 4","password":"1234"}]*/
		
		/**
		 * 将Json字符串转换成Person集合对象
		 */
		ArrayList mPersons = new ArrayList();
		JSONArray mJsonArray2;
		try {
			mJsonArray2 = new JSONArray(mJsonArray.toString());
			for(int j = 0;j < mJsonArray2.length();j++){
				Person mPerson = new Person();
				JSONObject mJsonObject = mJsonArray2.getJSONObject(j);
				mPerson.setId(mJsonObject.getInt("id"));
				mPerson.setUserName(mJsonObject.getString("userName"));
				mPerson.setPassword(mJsonObject.getString("password"));
				mPersons.add(mPerson);
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(mPersons.toString());
		/**打印的内容为:
		 * [Person [id=0, userName=AndroidLeaf 0, password=1230], 
		 *  Person [id=1, userName=AndroidLeaf 1, password=1231],
		 *  Person [id=2, userName=AndroidLeaf 2, password=1232], 
		 *  Person [id=3, userName=AndroidLeaf 3, password=1233], 
		 *  Person [id=4, userName=AndroidLeaf 4, password=1234]]*/
	}
	
	/**
	 * JsonString对象的使用
	 */
	public String jsonStringTest(){
		
		/**
		 * 将Person对象构建成Json字符串文本
		 */
		JSONStringer mJsonStringer = new JSONStringer();
		Person mPerson = testDataPerson();
		try {
			//object()和endObject()配对出现,用于描述对象开始解析
			mJsonStringer.object();
			mJsonStringer.key("id");
			mJsonStringer.value(mPerson.getId());
			mJsonStringer.key("userName");
			mJsonStringer.value(mPerson.getUserName());
			mJsonStringer.key("password");
			mJsonStringer.value(mPerson.getPassword());
			mJsonStringer.endObject();
			
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println(mJsonStringer.toString());
		/**打印的内容为: {"id":1,"userName":"AndroidLeaf","password":"123"}*/
		
		
		/**
		 * 将Person集合对象构建成Json字符串文本
		 * 
		 */
		
		JSONStringer mJsonStringer2 = new JSONStringer();
		ArrayList mList = testDataPersons();
		
		try {
			//array()和endArray()方法配对出现,用于描述数组对象开始解析
			mJsonStringer2.array();
			for(int i = 0 ;i < mList.size();i++){
				//将Person对象解析成Json字符串并包装成JSONStringer添加到数组集合中
				JSONStringer mJsonStringer3 = new JSONStringer();
				mJsonStringer3.object();
				mJsonStringer3.key("id");
				mJsonStringer3.value(mList.get(i).getId());
				mJsonStringer3.key("userName");
				mJsonStringer3.value(mList.get(i).getUserName());
				mJsonStringer3.key("password");
				mJsonStringer3.value(mList.get(i).getPassword());
				mJsonStringer3.endObject();
				mJsonStringer2.value(mJsonStringer3);
			}
			mJsonStringer2.endArray();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//System.out.println(mJsonStringer2.toString());
		return mJsonStringer2.toString();
		/**打印的内容为:["{\"id\":0,\"userName\":\"AndroidLeaf 0\",\"password\":\"1230\"}",
		 * "{\"id\":1,\"userName\":\"AndroidLeaf 1\",\"password\":\"1231\"}",
		 * "{\"id\":2,\"userName\":\"AndroidLeaf 2\",\"password\":\"1232\"}",
		 * "{\"id\":3,\"userName\":\"AndroidLeaf 3\",\"password\":\"1233\"}",
		 * "{\"id\":4,\"userName\":\"AndroidLeaf 4\",\"password\":\"1234\"}"]*/
		
	}
	
	/**
	 * JsonTokener对象的使用
	 */
	public void jsonTokenerTest(){
		
		/**jsonStr的内容为:["{\"id\":0,\"userName\":\"AndroidLeaf 0\",\"password\":\"1230\"}",
		 * "{\"id\":1,\"userName\":\"AndroidLeaf 1\",\"password\":\"1231\"}",
		 * "{\"id\":2,\"userName\":\"AndroidLeaf 2\",\"password\":\"1232\"}",
		 * "{\"id\":3,\"userName\":\"AndroidLeaf 3\",\"password\":\"1233\"}",
		 * "{\"id\":4,\"userName\":\"AndroidLeaf 4\",\"password\":\"1234\"}"]*/
		String jsonStr = initTokenerData();
		JSONTokener mJsonTokener = new JSONTokener(jsonStr);
		try {
			//跳转并读取到下一个字符
			System.out.println(mJsonTokener.next());
			//跳转并读取一个值
			System.out.println(mJsonTokener.nextValue());
			System.out.println(mJsonTokener.next());
			System.out.println(mJsonTokener.nextValue());
			//返回到上一个字符
			mJsonTokener.back();
			System.out.println(mJsonTokener.next());
			//跳转到下一个包含"f"字符的位置,并获取起初位置到跳转后位置之间的字符串
			System.out.println(mJsonTokener.nextTo('f'));
			//mJsonTokener.next(c);
			//mJsonTokener.next(arg0);
			//mJsonTokener.skipTo(arg0);
			//mJsonTokener.nextClean();
			
			/**打印的内容为:[
				*		{"id":0,"userName":"AndroidLeaf 0","password":"1230"}
				*		,
				*		{"id":1,"userName":"AndroidLeaf 1","password":"1231"}
				*		"
				*		,"{\"id\":2,\"userName\":\"AndroidLea*/
			
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public Person testDataPerson(){
		Person mPerson = new Person();
		mPerson.setId(1);
		mPerson.setUserName("AndroidLeaf");
		mPerson.setPassword("123");
		return mPerson;
	}
	
	public ArrayList testDataPersons(){
		ArrayList mList = new ArrayList();
		for(int i = 0; i < 5; i++){
			Person mPerson = new Person();
			mPerson.setId(i);
			mPerson.setUserName("AndroidLeaf " + i);
			mPerson.setPassword("123" + i);
			mList.add(mPerson);
		}
		return mList;
	}
	
	public String initTokenerData(){
		return jsonStringTest();
	}
}
基本上了解了Json的概念以及Json所提供的几个关键类的作用和使用方法后,接下来我们来正式学习如何在Android中使用Json来解析从服务端传送过来的Json数据,我们将通过一个具体的示例来深入学习一下。先整理一下示例的思路:我们创建一个Java服务端工程和Android客户端工程,然后在服务端将Java对象数据转换成Json字符串,接着Android客户端通过网络通信从服务端获取Json字符串数据,然后将Json数据使用Json数据解析方式解析成对应的Java对象,最后使用Listview列表展现数据。思路讲解完了后,有的读者可能依然理解得不太清楚,那么为了感觉更直观些,我们通过一个图来理解下:
Android中Json数据解析(一)--Json初步_第7张图片
接下来开始编写示例代码,下面我们创建一个Android工程,作为客户端,然后创建一个Web工程,作为服务端,下面是程序代码列表图,如下:
Android中Json数据解析(一)--Json初步_第8张图片     Android中Json数据解析(一)--Json初步_第9张图片
           图1-1 客户端                                                  图1-2服务端
首先我们来看一下服务端的代码,服务端我们使用Servlet返回一个所需要的Json字符串数据。我们在JsonService类中模拟从数据库中获取数据,具体代码如下:
public class JsonService {

	public JsonService() {
		// TODO Auto-generated constructor stub
	}

	public Person getPerson() {
		Person person = new Person();
		person.setId(1001);
		person.setUserName("jack");
		person.setPassword("123");
		return person;
	}

	public List getlistPerson() {
		List list = new ArrayList();
		Person person1 = new Person();
		person1.setId(1001);
		person1.setUserName("jack");
		person1.setPassword("123");
		Person person2 = new Person();
		person2.setId(1002);
		person2.setUserName("rose");
		person2.setPassword("123");
		Person person3 = new Person();
		person3.setId(1003);
		person3.setUserName("joly");
		person3.setPassword("123");
		list.add(person1);
		list.add(person2);
		list.add(person3);
		return list;
	}

	public List getListString() {
		List list = new ArrayList();
		list.add("jack");
		list.add("rose");
		list.add("joly");
		return list;
	}
	
	public ArrayList> getListMap(){
		ArrayList> mList = new ArrayList>();
		Map map = new HashMap();
		Person person1 = new Person();
		person1.setId(1001);
		person1.setUserName("jack");
		person1.setPassword("123");
		Person person2 = new Person();
		person2.setId(1002);
		person2.setUserName("rose");
		person2.setPassword("123");
		map.put("person1", person1);
		map.put("person2", person2);
		Map map2 = new HashMap();
		Person person3 = new Person();
		person3.setId(1003);
		person3.setUserName("joly");
		person3.setPassword("123");
		map2.put("person3", person3);
		Person person4 = new Person();
		person4.setId(1004);
		person4.setUserName("Steve");
		person4.setPassword("123");
		map2.put("person4", person4);
		mList.add(map);
		mList.add(map2);
		return mList;
	}
}
JsonTools类复杂将Java对象或集合转换成Json字符串,具体代码如下:
public class JsonTools {

	public static String createJsonString(String key, Object value) {
		/**
		 * 使用Json原生库解析数据时,使用该方法返回Json字符串
		 */
		
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(key, value);
		return jsonObject.toString();
		
		/**
		 * 使用Gson,Jackson和FastJson解析数据时,使用该方法返回Json字符串
		 */
		
		/*Gson mGson = new Gson();
		return mGson.toJson(value);*/
		
	}
}
Person为entity对象,具体的代码如下:
public class Person {
	
	private int id;
	private String userName;
	private String password;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", userName=" + userName + ", password="
				+ password + "]";
	}
	
}
UserGetServlet的作用是接受客户端请求,初始化Json数据,以及将数据返回给客户端,具体的代码如下:
/**
 * Servlet implementation class UserGetServlet
 */
public class UserGetServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	private JsonService mService;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public UserGetServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");

		PrintWriter out = response.getWriter();
		String jsonString = "";
		String action_flag = request.getParameter("action_flag");
		if (action_flag.equals("person")) {
			jsonString = JsonTools.createJsonString("person", mService
					.getPerson());
		} else if (action_flag.equals("listperson")) {
			jsonString = JsonTools.createJsonString("listperson", mService
					.getlistPerson());
		} else if (action_flag.equals("liststring")) {
			jsonString = JsonTools.createJsonString("liststring", mService
					.getListString());
		}else if(action_flag.equals("listmapperson")){
			jsonString = JsonTools.createJsonString("listmapperson", mService.getListMap());
		}
		out.println(jsonString);
		out.flush();
		out.close();
	}

	@Override
	public void init() throws ServletException {
		// TODO Auto-generated method stub
		super.init();
		mService = new JsonService();
	}
}
好的,服务端的代码我们便编写完毕,我们来运行一下程序,运行效果如下:
Android中Json数据解析(一)--Json初步_第10张图片
观察上面的运行结果,服务端成功返回Json字符串。接下来我们编写客户端的代码,首先我们看下客户端的网络访问程序HttpUtils和MyAsynctask类的代码,HttpUtils代码如下:
/**
 * 网络访问类
 * @author AndroidLeaf
 */
public class HttpUtils {
	
	/**
	 * 使用HttpURLConnection方式从网络中获取数据
	 * @param urlStr
	 * @return
	 */
	public static String getStringFromNetWork(String urlStr)
	{
		URL mUrl = null;
		HttpURLConnection  mConnection= null;
		String result = null;
		try {
			mUrl = new URL(urlStr);
			mConnection = (HttpURLConnection)mUrl.openConnection();
			mConnection.setDoOutput(true);
			mConnection.setDoInput(true);
			mConnection.setReadTimeout(5 * 1000);
			mConnection.setConnectTimeout(15 * 1000);
			mConnection.setRequestMethod("GET");
			int responseCode = mConnection.getResponseCode();
			if(responseCode == HttpURLConnection.HTTP_OK){
				//获取下载资源的大小
				//contentLength = mConnection.getContentLength();
				result = changeInputStreamToString(mConnection.getInputStream());
				return result;
			}		
		} catch (IOException e) {
			// TODO: handle exception
		}
		return "";
	}
	
	/**
	 * 将字节流数据转换成字符串
	 * @param mInputStream 需要转换的字节流
	 * @return result 转换后的结果
	 */
	private static String changeInputStreamToString(InputStream mInputStream)
	{
		ByteArrayOutputStream mArrayOutputStream = new ByteArrayOutputStream();
		String result = null;
		byte[] mBytes = new byte[2048];
		int len = -1;
		try {
			while((len = mInputStream.read(mBytes)) != -1)
			{
				mArrayOutputStream.write(mBytes, 0, len);
				mArrayOutputStream.flush();
			}
			result = new String(mArrayOutputStream.toByteArray(), "UTF-8");
			return result;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				if(mInputStream != null){
					mInputStream.close();
				}
				if(mArrayOutputStream != null){
					mArrayOutputStream.close();
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
		return "";
	}
}
接着是MyAsynctask类,该类主要作用是将网络请求放在异步任务中进行,以免阻塞UI线程,具体的代码如下:
/**
 * 异步任务处理类
 * @author AndroidLeaf
 */
public class MyAsynctask extends AsyncTask {

	/**
	 * 解析数据类型的ID
	 */
	 int typeId = -1;
	 
	 /**
	  * 定义一个回调,用于监听网络请求,当请求结束,返回访问结果
	  */
	 public HttpDownloadedListener mHttpDownloadedListener;
	
	 public interface HttpDownloadedListener{
		public void onDownloaded(String result,int typeId);
	 }
	 
	 public void setOnHttpDownloadedListener(HttpDownloadedListener mHttpDownloadedListener){
		 this.mHttpDownloadedListener = mHttpDownloadedListener;
	 }
	 
	@Override
	protected String doInBackground(Object... params) {
		// TODO Auto-generated method stub
		//执行网络访问请求
		String result = HttpUtils.getStringFromNetWork((String)params[0]);
		typeId = (int) params[1];
		return result;
	}

	@Override
	protected void onPostExecute(String result) {
		// TODO Auto-generated method stub
		super.onPostExecute(result);
		mHttpDownloadedListener.onDownloaded(result,typeId);
	}
}
网络访问的具体Url地址我们放在了Constants类中,Constants代码如下:
/**
 * 网络请求的Url地址
 * @author AndroidLeaf
 *
 */
public class Constants {

	public static final String BASE_PATH = "http://10.0.2.2:8080/08_Android_JsonServer_Blog/UserGetServlet?action_flag=";
	public static final String GET_PERSON_PATH = BASE_PATH + "person";
	public static final String GET_LISTPERSON_PATH = BASE_PATH + "listperson";
	public static final String GET_LISTSTRING_PATH = BASE_PATH + "liststring";
	public static final String GET_LISTMAPPERSON_PATH = BASE_PATH + "listmapperson";
}
从网络中获取到Json字符串数据后,我们接下来就应该将Json数据解析成Java对象或Java对象集合,我们看下JsonTools类中解析Json数据的代码如下:
public class JsonTools {

	/**-----------------Json数据解析----------------------------*/
	public static Person JsonToPerson(String key,String jsonStr)
	{
		Person mPerson = new Person();
		try {
			JSONObject mJsonObject = new JSONObject(jsonStr);
			JSONObject mJsonObject2 = mJsonObject.getJSONObject(key);

			mPerson.setId(mJsonObject2.getInt("id"));
			mPerson.setUserName(mJsonObject2.getString("userName"));
			mPerson.setPassword(mJsonObject2.getString("password"));
			
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return mPerson;
	}
	
	public static ArrayList JsonToListPerson(String key,String jsonStr)
	{
		
		ArrayList mPersons = new ArrayList();
		try {
			JSONObject mJsonObject = new JSONObject(jsonStr);
			JSONArray mArray = mJsonObject.getJSONArray(key);
			for(int i = 0 ; i < mArray.length() ; i++)
			{
				Person  mPerson = new Person();
				JSONObject mJsonObject2 = mArray.getJSONObject(i);
				mPerson.setId(mJsonObject2.getInt("id"));
				mPerson.setUserName(mJsonObject2.getString("userName"));
				mPerson.setPassword(mJsonObject2.getString("password"));
				mPersons.add(mPerson);
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return mPersons;
	}
	
	public static ArrayList jsonToListString(String key,String jsonStr)
	{
		ArrayList mStrings = new ArrayList();
		JSONObject mJsonObject;
		try {
			mJsonObject = new JSONObject(jsonStr);
			JSONArray mArray = mJsonObject.getJSONArray(key);
			for(int i = 0 ;i < mArray.length();i++)
			{
				mStrings.add(mArray.getString(i));
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
		return mStrings;
	}
	
	public static ArrayList> jsonToListMapPerson(String key,String jsonStr)
	{
		ArrayList> listMaps = new ArrayList>();
		try {
			JSONObject mJsonObject = new JSONObject(jsonStr);
			JSONArray mJsonArray = mJsonObject.getJSONArray(key);
			for(int i = 0 ;i < mJsonArray.length();i++)
			{
				JSONObject mJsonObject2 = mJsonArray.getJSONObject(i);
				Map maps = new HashMap();
				Iterator mIterator = mJsonObject2.keys();
				ArrayList mListKey = new ArrayList();
				ArrayList mListValue = new ArrayList();
				while(mIterator.hasNext())
				{
					String mapKey = mIterator.next();
					Object mObject = mJsonObject2.get(mapKey);
					System.out.println(mObject.toString());
					mListValue.add("{"+ mapKey + ":" + mObject.toString() + "}");
					mListKey.add(mapKey);
				}
				for(int j = 0; j < mListKey.size(); j++)
				{
					JSONObject mJsonObject3 = new JSONObject(mListValue.get(j));
					JSONObject mJsonObject4 = mJsonObject3.getJSONObject(mListKey.get(j));
					Person mPerson = new Person();
					mPerson.setId(mJsonObject4.getInt("id"));
					mPerson.setUserName(mJsonObject4.getString("userName"));
					mPerson.setPassword(mJsonObject4.getString("password"));
					maps.put(mListKey.get(j), mPerson);
				}
				listMaps.add(maps);
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return listMaps;
	}
}
将Json数据解析成对应的Java对象或集合后,最后我们将数据绑定到ListView控件上,并展示在客户界面,这里涉及到两个类BaseActivity和JsonActivity,BaseActivity类的代码如下:
public abstract class BaseActivity extends ListActivity implements HttpDownloadedListener{

	 public ProgressDialog mProgressDialog;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_json);
		//初始化数据
		initData();
		
	}

	public void initData(){
		mProgressDialog = new ProgressDialog(this);
		mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		mProgressDialog.setTitle("正在加载中.....");
		mProgressDialog.show();
		downloadData(Constants.GET_PERSON_PATH,R.id.json_person);
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TOdO Auto-generated method stub
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TOdO Auto-generated method stub
		String urlStr = null;
		int typeId = -1;
		switch (item.getItemId()) {
		case R.id.json_person:
			urlStr = Constants.GET_PERSON_PATH;
			typeId = R.id.json_person;
			break;
		case R.id.json_string:
			urlStr = Constants.GET_LISTSTRING_PATH;
			typeId = R.id.json_string;
		    break;
		case R.id.json_list_person:
			urlStr = Constants.GET_LISTPERSON_PATH;
			typeId = R.id.json_list_person;
			break;
		case R.id.json_listmap_person:
			urlStr = Constants.GET_LISTMAPPERSON_PATH;
			typeId = R.id.json_listmap_person;
			break;
		default:
			break;
		}
		downloadData(urlStr,typeId);
		mProgressDialog.show();
		return super.onOptionsItemSelected(item);
	}
	
	/**
	 * 根据Url地址下载数据
	 * @param urlStr Url地址
	 * @param typeId 下载的类型ID,这里使用控件ID
	 */
	public void downloadData(String urlStr,int typeId){
		MyAsynctask mAsynctask = new MyAsynctask();
		mAsynctask.setOnHttpDownloadedListener(this);
		mAsynctask.execute(urlStr,typeId);
	}
	
	public void bindData(ArrayList mList){
		ArrayAdapter mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1, mList);
		setListAdapter(mAdapter);
		if(mProgressDialog.isShowing()){
			mProgressDialog.dismiss();
		}
	}
	
	/**
	 * 将Person集合转换为String集合
	 * @param mList
	 * @return
	 */
	public ArrayList personsToString(ArrayList mList){
		ArrayList mStrings = new ArrayList();
		for(int i = 0;i < mList.size();i++){
			mStrings.add(mList.get(i).toString());
		}
		return mStrings;
	}
	
	/**
	 * 将Persons Map集合装换为String集合
	 * @param listMap
	 * @return
	 */
	public ArrayList listmappersonsToString(ArrayList> listMap){
		ArrayList mStrings = new ArrayList();
		for(Map map: listMap){
			 for(Map.Entry entry: map.entrySet()){
			    	mStrings.add(entry.getKey() +":"+ entry.getValue().toString());
			    }
		}
		return mStrings;
	}
}
JsonActivity代码如下:
public class JsonActivity extends BaseActivity {

	@Override
	public void onDownloaded(String result,int typeId) {
		// TODO Auto-generated method stub
		ArrayList mList = new ArrayList();
		switch (typeId) {
		case R.id.json_person:
			Person mPerson = JsonTools.JsonToPerson("person", result);
			mList.add(mPerson.toString());
			break;
		case R.id.json_string:
			ArrayList mArrayList = JsonTools.jsonToListString("liststring", result);
			mList.addAll(mArrayList);
			break;
		case R.id.json_list_person:
			ArrayList mPersons = JsonTools.JsonToListPerson("listperson", result);
			mList.addAll(personsToString(mPersons));
			break;
		case R.id.json_listmap_person:
			ArrayList> maps = JsonTools.jsonToListMapPerson("listmapperson", result);
			mList.addAll(listmappersonsToString(maps));
			break;
		default:
			break;
		}
		bindData(mList);
	}
	
}
至此,我们便将服务端和客户端的所有代码编写完毕,下面我们开始运行测试,首先运行服务端程序,然后再在Android模拟器中运行客户端程序,运行及操作效果如下图:
Android中Json数据解析(一)--Json初步_第11张图片

观察上图的运行效果,我们成功从服务端获取到Json数据,并使用Json解析技术将Json字符串数据解析成对应的Java对象或集合。

总结:Json解析作为常用的解析技术,Android开发者必须熟练掌握并使用。我们总结一下今天学的Json重要知识点:(1)Json的发展历史及特点;(2)Json数据的两种组织结构形式;(3)Json数据解析的应用实例操作。下一篇文章我们将介绍另外三种(Gson、Jackson和FastJson)Json解析技术,它们比原生态类库的提供Json解析技术使用起来更加简单、方便和高效,有兴趣的读者可以学习一下。

源代码下载,请戳下面:
  • GITHUB下载
  • CSDN下载

你可能感兴趣的:(Android应用开发)