在前面的两讲中,我们讲解了JSON数据格式的一些基本知识,以及做一些小Demo,这一讲我们在前面的基础上来做一个综合的可扩展的Demo,主要是针对Android客户端解析服务端传递过来的JSON数据。整个Demo所作的操作如下图所示

【Android 开发】: Android客户端与服务端之间使用JSON交互数据。_第1张图片

1. 服务端

   服务端我们需要用到的解析JSON的库是用org.json --> Java --> JSON-lib项目中的库json-lib-2.4-jdk15.jar,这个库还需要附带几个依赖包:commons-beanutils.jar, commons-httpclient.jar, commons- lang.jar, ezmorph.jar,morph-1.0.1.jar。具体的包我会放在源码的lib目录下,读者可以自己去下载。

   查看这个项目的api文档:http://json-lib.sourceforge.net/apidocs/jdk15/index.html,我们主要使用的是JSON JSONArray JSONObject JSONSerializer 这几个类,JSONObject这个类可以发现它与org.json这个项目的用法很类似。

   1) 先做一个服务端的小实验,就是在服务端实现对Java对象转换成JSON数据格式并且在控制台输出。

Person.java 普通的Person类

package com.json.domain;public class Person {    private int id;    private String name;    private String address;    public Person(int id, String name, String address) {        super();        this.id = id;        this.name = name;        this.address = address;    }    public Person() {        // TODO Auto-generated constructor stub    }    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 getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }}

JsonService.java 服务于Person,给Person对象赋予各种属性

package com.json.service;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.json.domain.Person;public class JsonService {       public JsonService() {        // TODO Auto-generated constructor stub    }    public Person getPerson(){        Person person = new Person(23, "AHuier", "XIAMEN");        return person;    }        public List getListPerson(){        List list = new ArrayList();        Person person1 = new Person(1001, "AHuier1", "Beijing");        Person person2 = new Person(1002, "AHuier2", "shenzheng");        list.add(person1);        list.add(person2);        return list;    }        public List getListString(){        List list = new ArrayList();        list.add("Hello");        list.add("World");        list.add("AHuier");        return list;    }        public List> getListMaps(){        List> listMap = new ArrayList>();        Map map1 = new HashMap();        map1.put("color", "red");        map1.put("id", 01);        map1.put("name", "Polu");        listMap.add(map1);        Map map2 = new HashMap();        map2.put("id", 07);        map2.put("color", "green");        map2.put("name", "Zark");        listMap.add(map2);        return listMap;     }   }
JsonTools.java 工具类
package com.json.tools;import net.sf.json.JSONObject;/** * @author xukunhui * 工具类,这里专门处理Java对象转Json字符串的功能 */public class JsonTools {    public JsonTools() {        // TODO Auto-generated constructor stub    }    /**     * @param key : JSON 名值对中的的名字     * @param value :JSON 名值对中的值,值可以有多种类型     * @return     */    // 接受对象转换为JSON数据格式并且作为字符串输出.    public static String createJsonString(String key, Object value){        JSONObject jsonObject = new JSONObject();        jsonObject.put(key, value);        return jsonObject.toString(); //就可以转换成Json数据格式    }    }
JsonTest.java 测试类
package com.json.test;import com.json.domain.Person;import com.json.service.JsonService;import com.json.tools.JsonTools;/** * @author xukunhui * 测试类,利用JSON讲Java对象转换成JSON数据格式,并且在控制台中输出 */public class JsonTest {    public JsonTest() {        // TODO Auto-generated constructor stub    }    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        String msg = "";        JsonService service = new JsonService();        // 带有三个属性的person对象        Person person = service.getPerson();        msg = JsonTools.createJsonString("person", person);        System.out.println(msg);                System.out.println("------------------------------");        // List中存放两个person对象,这两个对象有各自的三个属性        msg = JsonTools.createJsonString("persons", service.getListPerson());        System.out.println(msg);                System.out.println("------------------------------");        // List中存放三个字符串        msg = JsonTools.createJsonString("listString", service.getListString());        System.out.println(msg);                System.out.println("------------------------------");        // List中存放两个Map,两个Map中分别存放三个不同的属性        msg = JsonTools.createJsonString("listMap", service.getListMaps());        System.out.println(msg);            }}

编译执行结果:

{"person":{"address":"XIAMEN","id":23,"name":"AHuier"}}
------------------------------
{"persons":[{"address":"Beijing","id":1001,"name":"AHuier1"},{"address":"shenzheng","id":1002,"name":"AHuier2"}]}
------------------------------
{"listString":["Hello","World","AHuier"]}
------------------------------
{"listMap":[{"id":1,"color":"red","name":"Polu"},{"id":7,"color":"green","name":"Zark"}]}

【说明】:从这里可以发现在服务端利用JSON很方便的将Java对象转换成JSON数据格式。

【注意】:我们这边需要给加一个person的标示符,作为最外面的一个对象的名,我们在客户端解析数据的时候,其实不加person的标示符也是可以的,但是这样写的目的是把原有的对象转换成JSON数据格式之后,我们在外层再给予封装一层对象,便于后续利用外层的这个对象进行解析。如下图所示:

【Android 开发】: Android客户端与服务端之间使用JSON交互数据。_第2张图片

2) 现在我们将服务端的项目部署到Tomcat服务器(如何部署可以参考前面几篇博文),然后通过在浏览器的地址栏中传递不同的action值来获取相应的JSON数据格式,这样的话浏览器也会显示出请求服务解析好的JSON数据格式。实现好这一步骤之后,我们在服务端的工作也完成了。服务端的项目结构图如下所示:

【Android 开发】: Android客户端与服务端之间使用JSON交互数据。_第3张图片

JsonAction.java  Servlet类,处理根浏览器客户端通过不同的参数请求返回JSON数据。

package com.json.action;import java.io.IOException;import java.io.PrintWriter;import java.nio.charset.Charset;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.json.service.JsonService;import com.json.tools.JsonTools;/** * @author xukunhui * Servlet类,处理根浏览器客户端通过不同的参数请求返回JSON数据。 */public class JsonAction extends HttpServlet {    private JsonService service;        /**     * Constructor of the object.     */    public JsonAction() {        super();    }    /**     * Destruction of the servlet. 
*/ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet.
* * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } /** * The doPost method of the servlet.
* * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; Charset=utf-8"); request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter();         /*            * 如果是以下这种方式直接在浏览器地址栏中用  http://192.168.0.112:8080/JsonProject/servlet/JsonAction 请求即可         * String jsonString = JsonTools.createJsonString("person", service.getListPerson());         * out.print(jsonString); // 从服务端提取数据,并且输出的浏览器客户端。        */     // 根据不同的参数输出不同的JSON数据 String jsonString = ""; String action_flag = request.getParameter("action_flag"); if(action_flag.equals("person")) { jsonString = JsonTools.createJsonString("person", service.getPerson()); } else if(action_flag.equals("persons")){ jsonString = JsonTools.createJsonString("persons", service.getListPerson()); } else if(action_flag.equals("listString")) { jsonString = JsonTools.createJsonString("listString", service.getListString()); } else if(action_flag.equals("listMap")){ jsonString = JsonTools.createJsonString("listMap", service.getListMaps()); } out.print(jsonString); out.flush(); out.close(); } /** * Initialization of the servlet.
* * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here service = new JsonService(); }}
程序执行, 浏览器地址栏中输入与浏览器显示如下:

输入: http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=person
输出: {"person":{"address":"XIAMEN","id":23,"name":"AHuier"}}

输入:http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=persons
输出: {"persons":[{"address":"Beijing","id":1001,"name":"AHuier1"},{"address":"shenzheng","id":1002,"name":"AHuier2"}]}

输入:http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listString
输出: {"listString":["Hello","World","AHuier"]}

输入:http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listMap
输出: {"listMap":[{"id":1,"color":"red","name":"Polu"},{"id":7,"color":"green","name":"Zark"}]}

【备注】:自此,我们服务端模块的内容已经实现的差不多了,在服务端我们通常还结合JDBC进行操作。可以把JDBC的数据提取出来,提取出来的肯定是单条记录,或者是某一个集合。也就是服务端从JDBC数据库中提取到数据只要转换成JSON的数据格式后提供客户端进行显示。如下图所示:

【Android 开发】: Android客户端与服务端之间使用JSON交互数据。_第4张图片

2. 客户端

   上面我们已经写好了服务端的代码,现在我们开始进行Android客户端的操作。JSON的解析有一个规则就是服务端把对象转换成一个JSON的数据格式,而客户端需要把JSON格式换成对象,客户端主要是通过Http协议向服务端发出请求获得服务端的JSON数据。

   客户端项目结构如下图所示:

   【Android 开发】: Android客户端与服务端之间使用JSON交互数据。_第5张图片

1. 客户端需要通过网络去向服务端请求数据,所以需要在 manifest.xml 清单文件中定义好访问网络的属性

        
2. HttpUtils.java 负责从服务器请求获取到JSON数据格式的字符串
package com.android.jsonproject.http;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;/** * @author xukunhui 从服务器请求获取到JSON数据格式的字符串 */public class HttpUtils {    public HttpUtils() {        // TODO Auto-generated constructor stub    }    public static String getJsonContent(String url_path) {        try {            URL url = new URL(url_path);            HttpURLConnection connection = (HttpURLConnection) url.openConnection();            connection.setConnectTimeout(3000); // 请求超时时间3s            connection.setRequestMethod("GET");            connection.setDoInput(true);            int code = connection.getResponseCode(); // 返回状态码            if (code == 200) {                // 或得到输入流,此时流里面已经包含了服务端返回回来的JSON数据了,此时需要将这个流转换成字符串                return changeInputStream(connection.getInputStream());            }        } catch (Exception e) {            // TODO: handle exception        }        return "";    }    private static String changeInputStream(InputStream inputStream) {        // TODO Auto-generated method stub        String jsonString = "";        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();        int length = 0;        byte[] data = new byte[1024];        try {            while (-1 != (length = inputStream.read(data))) {                outputStream.write(data, 0, length);            }            // inputStream流里面拿到数据写到ByteArrayOutputStream里面,            // 然后通过outputStream.toByteArray转换字节数组,再通过new String()构建一个新的字符串。            jsonString = new String(outputStream.toByteArray());        } catch (Exception e) {            // TODO: handle exception        }        return jsonString;    }}
3. JSONTools.java 完成对从服务端请求获得的JSON数据的解析成指定的对象.
package com.android.jsonproject.json;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import org.json.JSONArray;import org.json.JSONObject;import com.android.jsonproject.domain.Person;/** * @author xukunhui * 完成对从服务端请求获得的JSON数据的解析成指定的对象. */public class JSONTools {    public JSONTools() {        // TODO Auto-generated constructor stub    }        // 此时从服务端取下来的数据是:{"person":{"address":"XIAMEN","id":23,"name":"AHuier"}}    public static Person getPerson(String key, String jsonString){        Person person = new Person();        try {            // 在Android官方文档中,org.json 这是Android提供给我们的解析json数据格式的包,            // 我们比较常用的是JSONArray 和 JSONObject这个两个类            JSONObject jsonObject = new JSONObject(jsonString);            JSONObject personObject = jsonObject.getJSONObject(key);            person.setId(personObject.getInt("id"));            person.setAddress(personObject.getString("address"));            person.setName(personObject.getString("name"));        } catch (Exception e) {            // TODO: handle exception        }        return person;    }        //{"persons":[{"address":"Beijing","id":1001,"name":"AHuier1"},{"address":"shenzheng","id":1002,"name":"AHuier2"}]}    public static List getPersons(String key, String jsonString){        List list = new ArrayList();        try {            JSONObject jsonObject = new JSONObject(jsonString);            //返回json的数组            JSONArray jsonArray = jsonObject.getJSONArray(key);            for(int i = 0; i < jsonArray.length(); i++){                JSONObject jsonObject2 = jsonArray.getJSONObject(i);                Person person = new Person();                person.setId(jsonObject2.getInt("id"));                person.setName(jsonObject2.getString("name"));                person.setAddress(jsonObject2.getString("address"));                list.add(person);            }        } catch (Exception e) {            // TODO: handle exception        }        return list;    }        //{"listString":["Hello","World","AHuier"]}    public static List getListString(String key, String jsonString){        List listString = new ArrayList();        try {            JSONObject jsonObject = new JSONObject(jsonString);            //返回JSON的数组            JSONArray jsonArray = jsonObject.getJSONArray(key);            for(int i = 0; i < jsonArray.length(); i++){                String msg = jsonArray.getString(i);                listString.add(msg);            }        } catch (Exception e) {            // TODO: handle exception        }        return listString;    }        // 此时从服务端取下来的数据是:{"listMap":[{"id":1,"color":"red","name":"Polu"},{"id":7,"color":"green","name":"Zark"}]}    public static List> getListMaps(String key, String jsonString){        List> listMap = new ArrayList>();        try {            JSONObject jsonObject = new JSONObject(jsonString);            JSONArray jsonArray = jsonObject.getJSONArray(key);            for(int i = 0; i < jsonArray.length(); i++){                JSONObject jsonObject2 = jsonArray.getJSONObject(i);                Map map = new HashMap();                // 通过org.json中的迭代器来取Map中的值。                Iterator iterator = jsonObject2.keys();                while(iterator.hasNext()) {                    String jsonKey = iterator.next();                    Object jsonValue = jsonObject2.get(jsonKey);                    //JSON的值是可以为空的,所以我们也需要对JSON的空值可能性进行判断。                    if(jsonValue == null){                        jsonValue = "";                    }                    map.put(jsonKey, jsonValue);                }                listMap.add(map);            }        } catch (Exception e) {            // TODO: handle exception        }        return listMap;    }    }
4. Person.java 配合客户端将JSON数据转换成Java对象,服务端有Person对象,所以客户端需要相应的Person对象
package com.android.jsonproject.domain;public class Person {    private int id;    private String name;    private String address;    public Person(int id, String name, String address) {        super();        this.id = id;        this.name = name;        this.address = address;    }    public Person() {        // TODO Auto-generated constructor stub    }    @Override    public String toString() {        return "Person [id=" + id + ", name=" + name + ", address=" + address + "]";    }    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 getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }}
5. Android 客户端主界面代码,这里主要是定义四个按钮分别处理解析不同类型的JSON数据格式,布局文件这里不再贴出.
    @Override    public void onClick(View v) {        // TODO Auto-generated method stub        switch (v.getId()) {            case R.id.person:                  String path = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=person";                String jsonString = HttpUtils.getJsonContent(path);                Log.i(TAG, "The jsonString:" + jsonString);                Person person = JSONTools.getPerson("person", jsonString);                Log.i(TAG, "The person:" + person.toString());                break;            case R.id.persons:                String path2 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=persons";                String jsonString2 = HttpUtils.getJsonContent(path2);                Log.i(TAG, "The jsonString:" + jsonString2);                List list2 = JSONTools.getPersons("persons", jsonString2);                Log.i(TAG, "The persons:" + list2.toString());                break;            case R.id.liststring:                String path3 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listString";                String jsonString3 = HttpUtils.getJsonContent(path3);                Log.i(TAG, "The jsonString:" + jsonString3);                List list3 = JSONTools.getListString("listString", jsonString3);                Log.i(TAG, "The listString:" + list3.toString());                break;            case R.id.listmap:                String path4 = "http://192.168.0.112:8080/JsonProject/servlet/JsonAction?action_flag=listMap";                String jsonString4 = HttpUtils.getJsonContent(path4);                Log.i(TAG, "The jsonString:" + jsonString4);                List> list4 = JSONTools.getListMaps("listMap", jsonString4);                Log.i(TAG, "The listMap:" + list4.toString());                break;        }    }
客户端编译执行结果:

【Android 开发】: Android客户端与服务端之间使用JSON交互数据。_第6张图片

1. 点击解析person数据按钮

2. 点击解析List嵌套person数据

3. 点击List嵌套String数据

4. 点击List嵌套Map数据

自此,Android客户端与服务之间的JSON数据交互的Demo就完成了,下面附上源代码,读者可以自行编译执行

服务端: MyEclipse + Tomcat + Servlet

客户端: Eclipse + Android(模拟器和真机都可以,但是必须保证通过IP地址可以访问)

源码下载:http://download.csdn.net/detail/xukunhui2/6546095

服务端(符JSON开源项目包路径:JsonProject\WebRoot\WEB-INF\lib):

客户端:http://download.csdn.net/detail/xukunhui2/6546117


接下去,我们会学习一下google-gson的数据格式的解析,敬请关注。


  

更多相关文章

  1. 新浪微博开放平台开发-android客户端(2)
  2. JavaEye Android 客户端正式发布
  3. 深入Android【八】 —— Activity间数据传输
  4. 快速开发框架Afinal的使用(数据库操作,HTTP请求,网络图片加载,控件绑
  5. Android开发小记--开发实用工具类--数据库操作类
  6. android差分更新之服务端
  7. php实现post请求 接收android客户端json数据 存储数据库 并返回j
  8. Android中用Application类实现全局数据变量的使用
  9. Android仿人人客户端(v5.7.1)——个人主页(一)

随机推荐

  1. 用 Python 来了解一下《安家》
  2. 让隐藏视窗的Dock成半透明状态
  3. 【微信小程序】自定义导航栏(一)
  4. 【微信小程序】自定义导航栏(二)
  5. 如何在Safari浏览器中设置活跃及其他网站
  6. 20210225-1 Python错误与异常
  7. 如何在Mac上的“照片”中使用滤镜来更改
  8. 【DB宝41】监控利器PMM的使用--监控MySQL
  9. 【免费开源】基于Vue和Quasar的crudapi前
  10. MySql数据库列表数据分页查询、全文检索A