移动云

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 3704|回复: 0

Android网络开发中如何使用JSON进行网络通信---Android JSON数据通

[复制链接]
发表于 2012-2-21 16:53:35 | 显示全部楼层 |阅读模式
在开发客户端与服务端的应用当中,数据交换接口通常都是通过XML格式来进行数据交换的。近年来,随着AJAX技术的兴起,JSON作为一种轻量级的数据交换格式,以其易于阅读和编写的优点,也越来越多的被使用到各个项目中。在OPhoneSDK中,也提供了JSON的类库方便对JSON格式的数据进行处理。本文将快速讲解JSON 格式,并通过代码示例演示如何分别在客户端和服务器端进行JSON 格式数据的处理。

什么是JSON
       JSON
JavaScriptObjectNotation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成,非常适合于服务器与客户端的交互。JSON采用与编程语言无关的文本格式,但是也使用了类C语言的习惯,这些特性使JSON成为理想的数据交换格式。
XML 一样,JSON也是基于纯文本的数据格式。由于JSON 天生是为JavaScript 准备的,因此,JSON的数据格式非常简单,您可以用JSON 传输一个简单的StringNumberBoolean,也可以传输一个数组,或者一个复杂的Object 对象。

      String
NumberBooleanJSON表示非常简单。例如,用JSON 表示一个简单的字符串“ abc ”,其格式为:"abc"

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



1.String的完整表示结构

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



2.Number的表示结构

         
这与绝大多数编程语言的表示方法一致,例如:  
12345
(整数)
-3.9e10
(浮点数)

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

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


1.["abc" , 12345 , false , null ]   
["abc",12345,false,null]      Object
对象在 JSON中是用 {}包含一系列无序的Key-Value 键值对表示的,实际上此处的Object 相当于Java 中的Map<String, Object>,而不是Java Class 。注意Key 只能用String 表示。例如,一个Address 对象包含如下Key-Value

city:Beijing
street:ChaoyangRoad
postcode:100025
(整数)

JSON表示如下:


1.{"city" : "Beijing" , "street" : "Chaoyang Road " , "postcode" : 100025 }  
{"city":"Beijing","street":"Chaoyang Road ","postcode":100025}      
其中Value 也可以是另一个Object 或者数组,因此,复杂的Object 可以嵌套表示,例如,一个Person 对象包含name address 对象,可以表示如下:


1.{"name" : "Michael" , "address" :   
2.   {"city" : "Beijing" , "street" : "Chaoyang Road " , "postcode" : 100025 }   
3.}  
{"name":"Michael","address":
   {"city":"Beijing","street":"Chaoyang Road ","postcode":100025}
}
一个实际例子
     
接下来,我会通过一个例子来详细说明OPhone客户端程序如何访问服务端的接口程序读取用户列表数据,并在模拟器上显示用户列表数据。

1
、服务端接口程序
     
首先,我们创建一个名为UserJavaBean作为用户对象类,用来保存演示数据。


1.public  class  User {   
2.   private   int  id;   
3.   private  String name;   
4.   private  String email;   
5.   private  String gender;   
6.      
7.   public   int  getId() {   
8.       return  id;   
9.   }   
10.   public   void  setId( int  id) {   
11.       this .id = id;   
12.   }   
13.   public  String getName() {   
14.       return  name;   
15.   }   
16.   public   void  setName(String name) {   
17.       this .name = name;   
18.   }   
19.   public  String getEmail() {   
20.       return  email;   
21.   }   
22.   public   void  setEmail(String email) {   
23.       this .email = email;   
24.   }   
25.   public  String getGender() {   
26.       return  gender;   
27.   }   
28.   public   void  setGender(String gender) {   
29.       this .gender = gender;   
30.   }   
31.      
32.}  
publicclass User {
   private int id;
   private String name;
   private String email;
   private String gender;
   
   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 String getEmail() {
       return email;
   }
   public void setEmail(String email) {
       this.email = email;
   }
   public String getGender() {
       return gender;
   }
   public void setGender(String gender) {
       this.gender = gender;
   }
   
}
   
接下来,我们创建一个名为JSONDemoServletServlet类来作为服务端的接口程序。在这个程序里,定义了一个List对象用来保存用户列表。


1.private List<User> list;   
privateList<User> list;      
客户端程序访问服务器端接口时,接口通过prepareData方法为用户列表初始化数据,添加用户数据到List对象中。


1.private  void  prepareData(){   
2.       list = new  ArrayList<User>();   
3.       User bean1 = new  User();   
4.       bean1.setId(1001 );   
5.       bean1.setName("Tony" );   
6.       bean1.setEmail("tony@toeach.net§");   
7.       bean1.setGender("male" );   
8.       list.add(bean1);   
9.       ……   
10.   }   
privatevoid prepareData(){
       list = new ArrayList<User>();
       User bean1 = new User();
       bean1.setId(1001);
       bean1.setName("Tony");
       bean1.setEmail("tony@toeach.net§");
       bean1.setGender("male");
       list.add(bean1);
       ……
   }
     
接着遍历用户列表,把列表中的每个Java用户对象转换为JSONObject对象,再加入到JSONArray中去。


1.JSONArrayarray =  new  JSONArray();   
2.   for (User bean:list){   
3.       //
单个用户JSON对象   
4.       JSONObject obj = new  JSONObject();   
5.              
6.       try {   
7.           obj.put("id" , bean.getId());   
8.           obj.put("name" , bean.getName());   
9.           obj.put("email" , bean.getEmail());   
10.           obj.put("gender" , bean.getGender());   
11.       } catch  (Exception e) {}   
12.              
13.           array.put(obj);   
14.   }   
JSONArrayarray = new JSONArray();
   for(User bean:list){
       //
单个用户JSON对象
       JSONObject obj = new JSONObject();
            
       try{
           obj.put("id", bean.getId());
           obj.put("name", bean.getName());
           obj.put("email", bean.getEmail());
           obj.put("gender", bean.getGender());
       } catch (Exception e) {}
            
           array.put(obj);
   }
      
最后,通过 Servlet输出JSON 时,需要设置正确的MIME 类型和字符编码。假定服务器使用UTF-8 编码,则可以使用以下代码输出编码后的JSON 文本:


1.response.setContentType("text/plain" );   
2.   response.setCharacterEncoding("UTF-8" );   
3.   PrintWriter out = response.getWriter();  
4.out.write(array.toString());  
5.   out.flush();   
6.   out.close();   
7.  
8.JSONDemoServlet.java
的完整代码如下:  
9.import java.io.IOException;   
10.import java.io.PrintWriter;   
11.import java.util.ArrayList;   
12.import java.util.List;   
13.  
14.import javax.servlet.ServletException;   
15.import javax.servlet.http.HttpServlet;   
16.import javax.servlet.http.HttpServletRequest;   
17.import javax.servlet.http.HttpServletResponse;   
18.  
19.import org.json.JSONArray;   
20.import org.json.JSONObject;   
21.  
22.public  class  JSONDemoServlet  extends  HttpServlet{   
23.   private   static   final   long  serialVersionUID =-7368225680407826408L;   
24.   private  List<User> list;   
25.      
26.   /**   
27.    *
处理post方式提交的数据  
28.    */     
29.   public   void  doPost(HttpServletRequest request,HttpServletResponse response) throws  ServletException, IOException {  
30.       doGet(request,response);   
31.   }   
32.       /**   
33.       *
出来get方式提交的数据  
34.       */     
35.       public   void  doGet(HttpServletRequest request,HttpServletResponse response)  throws  ServletException, IOException{   
36.           response.setContentType("text/plain" );   
37.           response.setCharacterEncoding("UTF-8" );   
38.           PrintWriter out = response.getWriter();   
39.         
40.           //
准备用户数据   
41.           prepareData();   
42.         
43.           //JSON
数组     
44.           JSONArray array = new  JSONArray();   
45.           for (User bean:list){   
46.               //
单个用户JSON对象   
47.               JSONObject obj = new  JSONObject();   
48.              
49.               try {   
50.                   obj.put("id" , bean.getId());   
51.                   obj.put("name" , bean.getName());   
52.                   obj.put("email" , bean.getEmail());  
53.                   obj.put("gender" , bean.getGender());  
54.               } catch  (Exception e) {}   
55.              
56.                   array.put(obj);   
57.           }   
58.         
59.           //
输出     
60.           out.write(array.toString());   
61.           out.flush();   
62.           out.close();   
63.       }   
64.       private   void  prepareData(){   
65.           list = new  ArrayList<User>();   
66.           User bean1 = new  User();   
67.           bean1.setId(1001 );   
68.           bean1.setName("Tony" );   
69.           bean1.setEmail("tony@toeach.net§");   
70.           bean1.setGender("male" );   
71.           list.add(bean1);   
72.         
73.           User bean2 = new  User();   
74.           bean2.setId(1002 );   
75.           bean2.setName("Jack" );   
76.           bean2.setEmail("jack@hotmail.com§");   
77.           bean2.setGender("male" );   
78.           list.add(bean2);   
79.         
80.           User bean3 = new  User();   
81.           bean3.setId(1003 );   
82.           bean3.setName("Marry" );   
83.           bean3.setEmail("marry@163.com§");   
84.           bean3.setGender("female" );   
85.           list.add(bean3);   
86.         
87.           User bean4 = new  User();   
88.           bean4.setId(1004 );   
89.           bean4.setName("Linda" );   
90.           bean4.setEmail("linda@21cn.com§");   
91.           bean4.setGender("female" );   
92.           list.add(bean4);   
93.       }   
94.}  
response.setContentType("text/plain");
   response.setCharacterEncoding("UTF-8");
   PrintWriter out = response.getWriter();
out.write(array.toString());
   out.flush();
   out.close();

JSONDemoServlet.java
的完整代码如下:
importjava.io.IOException;
importjava.io.PrintWriter;
importjava.util.ArrayList;
importjava.util.List;

importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;

importorg.json.JSONArray;
importorg.json.JSONObject;

publicclass JSONDemoServlet extends HttpServlet{
   private static final long serialVersionUID =-7368225680407826408L;
   private List<User> list;
   
   /**
    *
处理post方式提交的数据
    */
   public void doPost(HttpServletRequest request, HttpServletResponseresponse)throws ServletException, IOException {
       doGet(request,response);
   }
       /**
        *
出来get方式提交的数据
        */
       public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
           response.setContentType("text/plain");
           response.setCharacterEncoding("UTF-8");
           PrintWriter out = response.getWriter();
        
           //
准备用户数据
           prepareData();
        
           //JSON
数组
           JSONArray array = new JSONArray();
           for(User bean:list){
               //
单个用户JSON对象
               JSONObject obj = new JSONObject();
            
               try{
                   obj.put("id", bean.getId());
                   obj.put("name", bean.getName());
                   obj.put("email", bean.getEmail());
                   obj.put("gender", bean.getGender());
               } catch (Exception e) {}
            
                   array.put(obj);
           }
        
           //
输出
           out.write(array.toString());
           out.flush();
           out.close();
       }
       private void prepareData(){
           list = new ArrayList<User>();
           User bean1 = new User();
           bean1.setId(1001);
           bean1.setName("Tony");
           bean1.setEmail("tony@toeach.net§");
           bean1.setGender("male");
           list.add(bean1);
        
           User bean2 = new User();
           bean2.setId(1002);
           bean2.setName("Jack");
           bean2.setEmail("jack@hotmail.com§");
           bean2.setGender("male");
           list.add(bean2);
        
           User bean3 = new User();
           bean3.setId(1003);
           bean3.setName("Marry");
           bean3.setEmail("marry@163.com§");
           bean3.setGender("female");
           list.add(bean3);
        
           User bean4 = new User();
           bean4.setId(1004);
           bean4.setName("Linda");
           bean4.setEmail("linda@21cn.com§");
           bean4.setGender("female");
           list.add(bean4);
       }
}
     
把该Servlet部署到Tomcat下,在浏览器输入接口地址http://localhost:8080/article/JSONDemoServlet§,输出结果如下:
[{"id":1001,"email":"tony@toeach.net§","name":"Tony","gender":"male"},{"id":1002,"email":"jack@hotmail.com§","name":"Jack","gender":"male"},{"id":1003,"email":"marry@163.com§","name":"Marry","gender":"female"},{"id":1004,"email":"linda@21cn.com§","name":"Linda","gender":"female"}]

2
、手机客户端程序
   
准备好服务端的接口后,接下来就是准备写客户端的程序了。打开Eclipse新建一个OPhone项目。我们创建一个名为MainActivityActivity类,如下图所示:



      
因为要访问外部网络,所以要在AndroidManifest.xml文件里增加一行安全许可:
<uses-permissionandroid:name="android.permission.INTERNET"/>

      
这样我们的应用程序就可以访问网络了。

      
接着修改布局文件res\layout\main.xml,增加一个TextView对象,用来显示解析后的用户数据。


1.<?xmlversion= "1.0"  encoding= "utf-8" ?>  
2.<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"   
3.   androidrientation="vertical"     
4.   android:layout_width="fill_parent"     
5.   android:layout_height="fill_parent" >   
6.   <TextView android:id="@+id/textView"     
7.       android:layout_width="fill_parent"     
8.       android:layout_height="fill_parent" />  
9.</LinearLayout>  
<?xmlversion="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
   androidrientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">
   <TextView android:id="@+id/textView"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"/>
</LinearLayout>
     OPhoneSDK
提供了ApacheHttpClient类处理网络访问,相信很多读者朋友都在其他项目当中用到过HttpClient。我写了一个方法,获取某一网址的网页内容,代码如下:


1./**  
2.*
获取网址内容   
3.* @param url   
4.* @return   
5.* @throws Exception   
6.*/     
7.private String getContent(String url)  throws  Exception{   
8.   StringBuilder sb = new  StringBuilder();   
9.      
10.   HttpClient client = new  DefaultHttpClient();   
11.   HttpParams httpParams = client.getParams();   
12.   //
设置网络超时参数   
13.   HttpConnectionParams.setConnectionTimeout(httpParams, 3000 );  
14.   HttpConnectionParams.setSoTimeout(httpParams, 5000 );   
15.   HttpResponse response = client.execute(new  HttpGet(url));   
16.   HttpEntity entity = response.getEntity();   
17.   if  (entity !=  null ) {   
18.       BufferedReader reader = new  BufferedReader( new InputStreamReader(entity.getContent(),  "UTF-8" ),  8192 );  
19.         
20.       String line = null ;   
21.       while  ((line = reader.readLine())!=  null ){   
22.           sb.append(line + "\n" );   
23.       }   
24.       reader.close();   
25.   }   
26.   return  sb.toString();   
27.}  
/**
*
获取网址内容
*@param url
*@return
*@throws Exception
*/
privateString getContent(String url) throws Exception{
   StringBuilder sb = new StringBuilder();
   
   HttpClient client = new DefaultHttpClient();
   HttpParams httpParams = client.getParams();
   //
设置网络超时参数
   HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
   HttpConnectionParams.setSoTimeout(httpParams, 5000);
   HttpResponse response = client.execute(new HttpGet(url));
   HttpEntity entity = response.getEntity();
   if (entity != null) {
       BufferedReader reader = new BufferedReader(newInputStreamReader(entity.getContent(), "UTF-8"), 8192);
        
       String line = null;
       while ((line = reader.readLine())!= null){
           sb.append(line + "\n");
       }
       reader.close();
   }
   return sb.toString();
}
      
修改MainActivity.java,在onCreate方法里增加解析服务端接口内容的代码,如下所示:


1.@Override   
2.public  void  onCreate(Bundle savedInstanceState) {   
3.   super .onCreate(savedInstanceState);   
4.   setContentView(R.layout.main);   
5.      
6.   try {   
7.           StringBuffer sb = new  StringBuffer();   
8.       //
在测试过程中,经常是用本机做测试服务器,访问本机的IP地址要设置为10.0.2.2   
9.       String url = "http://10.0.2.2:8080/article/JSONDemoServlet";   
10.       String body = getContent(url);   
11.       JSONArray array = new  JSONArray(body);   
12.       for ( int  i= 0 ; i<array.length(); i++){   
13.           JSONObject obj = array.getJSONObject(i);   
14.           sb.append("id:" ).append(obj.getInt( "id")).append( "\t" );   
15.           sb.append("name:" ).append(obj.getString( "name")).append( "\r\n" );   
16.           sb.append("gender:" ).append(obj.getString("gender" )).append( "\t" );   
17.           sb.append("email:" ).append(obj.getString("email" )).append( "\r\n" );   
18.           sb.append("----------------------\r\n" );   
19.       }   
20.       TextView textView = (TextView)findViewById(R.id.textView);  
21.       textView.setText(sb.toString());   
22.   }catch (Exception e){}   
23.}  
@Override
publicvoid onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);
   
   try{
           StringBuffer sb = new StringBuffer();
       //
在测试过程中,经常是用本机做测试服务器,访问本机的IP地址要设置为10.0.2.2
       String url = "http://10.0.2.2:8080/article/JSONDemoServlet";
       String body = getContent(url);
       JSONArray array = new JSONArray(body);
       for(int i=0; i<array.length(); i++){
           JSONObject obj = array.getJSONObject(i);
           sb.append("id:").append(obj.getInt("id")).append("\t");
          sb.append("name:").append(obj.getString("name")).append("\r\n");
          sb.append("gender:").append(obj.getString("gender")).append("\t");
          sb.append("email:").append(obj.getString("email")).append("\r\n");
           sb.append("----------------------\r\n");
       }
       TextView textView = (TextView)findViewById(R.id.textView);
       textView.setText(sb.toString());
   }catch(Exception e){}
}

总结
      
本文简单介绍了JSON的相关知识,以及在Android平台中如何通过JSON来和服务端的应用进行数据交换。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|管理员QQ:44994224|邮箱(t268studio@gmail.com)|Archiver|MCLOUDER

GMT+8, 2025-7-2 06:17 , Processed in 0.064594 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表