上篇博客,我们谈到了XML两种常用的解析技术,详细可以参见我的博客(android基础---->XMl数据的解析)。网络传输另外一种数据格式JSON就是我们今天要讲的,它是比XML体积更小的数据格式,在网络上传输的时候可以更省流量。JSON解析的框架有很多,我们就讲使用JSONObject和Gson两种,好了我们开始Json的讲解。

目录导航:

  1. JSONObject常见的使用
  2. JSONObject的实现原理
  3. Gson常见的使用
  4. JSON的使用实例
  5. 友情链接

JSONObject的使用

一、 JSON对象的使用:

String content = "{'username': 'linux', 'password': '123456'}";
JSONObject jsonObject = new JSONObject(content);
String username = jsonObject.getString("username");
String password = jsonObject.getString("password");

二、 JSON数组的使用:

String jsonContent = "[{'user': '刘力', 'age': 21, 'femal': true}, "
                        + "{'user': 'chen', 'age': 20, 'femal': false}]";
JSONArray jsonArray = new JSONArray(jsonContent);
for (int i = 0; i < jsonArray.length(); i++) {
      JSONObject object = jsonArray.getJSONObject(i);
      System.out.print(object.getString("user") + " ");
      System.out.print(object.getInt("age") + " ");
      System.out.print(object.getBoolean("femal") + " ");
      System.out.println();
}

三、 JSON数组与JSON对象混合使用

String jsonString = "[{'user': 'tomhu', 'age': 21, " + "'info': {'adress': 'hubai', 'sex': 'femal'}}, "
+ "{'user': 'chen', 'age': 20, " + "'info': {'adress': 'hunan', 'sex': 'male'}}]";
JSONArray jsonArrays = new JSONArray(jsonString);
for (int i = 0; i < jsonArrays.length(); i++) {
JSONObject objects = jsonArrays.getJSONObject(i);
System.out.print(objects.getString("user") + " ");
System.out.print(objects.getInt("age") + " ");
System.out.print(objects.getJSONObject("info").getString("adress") + " ");
System.out.print(objects.getJSONObject("info").getString("sex") + " ");
System.out.println();
}

四、 JSON数组中存储对象

Person person = new Person();
person.setUsername("linux" );
person.setPassword("123456" );
JSONArray jsonArray = new JSONArray();
jsonArray.put(0, person );
jsonArray.put(1, "I love you" ); // String username = jsonArray.getJSONObject(0).getString("username"); 错误的写法
Person user = (Person) jsonArray.get(0);
System.out.println("username: " + user.getUsername());

JSONObject的原理

JsonObject的存储与取出

一、 JSONObject里面维护了一个LinkedHashMap,当生成一个无参数的JSONObject,实质是初始化了一个Map:

private final LinkedHashMap<String, Object> nameValuePairs;
public JSONObject() {
nameValuePairs = new LinkedHashMap<String, Object>();
}

二、 当JSONObject增加数据,实质上把数据的键值对方法存放在上述的Map中:

public JSONObject put(String name, boolean value) throws JSONException {
nameValuePairs.put(checkName(name), value);
return this;
}

三、 从JSONObject中取出数据,很容易想到的就是从Map取出了:

public String getString(String name) throws JSONException {
Object object = get(name); // get()方法就是执行Object result = nameValuePairs.get(name);
String result = JSON.toString(object);
if (result == null) {
throw JSON.typeMismatch(name, object, "String");
}
return result;
}

JsonObject的解析过程

一、 JsonObject还有一个带参数的构造函数:常用的是传递一个String类型的参数

public JSONObject(String json) throws JSONException {
this(new JSONTokener(json));
}

二、 跟进去,发现主要执行的是JSONTokener的nextValue()方法,在这个方法中主要是对数据进行解析;

public Object nextValue() throws JSONException {
int c = nextCleanInternal();
switch (c) {
case -1:
throw syntaxError("End of input"); case '{':
return readObject(); case '[':
return readArray(); case '\'':
case '"':
return nextString((char) c); default:
pos--;
return readLiteral();
}
}
  • 在nextCleanInternal方法中,它会从头到尾的逐个字符的解析,对于一些字符做一些处理。例如空格,换行,转义符等!
  • 当解析到[表示开始一个对象的读取,当解析到{表示一个数组的读取

三、 在readObject方法中,仍然是调用nextCleanInternal()方法,逐个得到解析的字符,下到解析到}.下面贴出重要代码

int first = nextCleanInternal();  // 得到解析的字符
if (first == '}') {
return result;
} else if (first != -1) {
pos--;
}
.......
while (true) {
Object name = nextValue(); // 解析得到键 int separator = nextCleanInternal();
if (separator != ':' && separator != '=') {
throw syntaxError("Expected ':' after " + name);
}
if (pos < in.length() && in.charAt(pos) == '>') {
pos++;
} result.put((String) name, nextValue()); // 将解析得到的键值对,存放在map当中 switch (nextCleanInternal()) {
case '}':
return result;
case ';':
case ',':
continue;
default:
throw syntaxError("Unterminated object");
}
}

四、 nextValue方法比较关键,它流转解析的大部分工作!在nextValue中有一个readLiteral方法,针对一些类型做处理,得到解析之后的结果:

private Object readLiteral() throws JSONException {
String literal = nextToInternal("{}[]/\\:,=;# \t\f"); if (literal.length() == 0) {
throw syntaxError("Expected literal value");
} else if ("null".equalsIgnoreCase(literal)) {
return JSONObject.NULL;
} else if ("true".equalsIgnoreCase(literal)) {
return Boolean.TRUE;
} else if ("false".equalsIgnoreCase(literal)) {
return Boolean.FALSE;
} /* try to parse as an integral type... */
if (literal.indexOf('.') == -1) {
int base = 10;
String number = literal;
if (number.startsWith("0x") || number.startsWith("0X")) {
number = number.substring(2);
base = 16;
} else if (number.startsWith("0") && number.length() > 1) {
number = number.substring(1);
base = 8;
}
try {
long longValue = Long.parseLong(number, base);
if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
return (int) longValue;
} else {
return longValue;
}
} catch (NumberFormatException e) {
/*
* This only happens for integral numbers greater than
* Long.MAX_VALUE, numbers in exponential form (5e-10) and
* unquoted strings. Fall through to try floating point.
*/
}
} /* ...next try to parse as a floating point... */
try {
return Double.valueOf(literal);
} catch (NumberFormatException ignored) {
} /* ... finally give up. We have an unquoted string */
return new String(literal); // a new string avoids leaking memory
}

五、至于JSONArray的解析与JsonObject的解析过程是一样的,它里面维护的是一个List:

private final List<Object> values;
public JSONArray(JSONTokener readFrom) throws JSONException {
Object object = readFrom.nextValue();
if (object instanceof JSONArray) {
values = ((JSONArray) object).values;
} else {
throw JSON.typeMismatch(object, "JSONArray");
}
}

Gson的使用

一、我们在测试当中先加入一个Person类,方便测试:

package com.tomhu.test;
public class Person {
private String name;
private int age; public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

二、 gson把对象转换成JSON格式

Gson gson = new Gson();
Person person = new Person();
person.setName("linux");
person.setAge(23);
String str = gson.toJson(person);
System.out.println(str);
  • 打印结果:  {"name":"linux","age":23}

三、 gson把json格式解析成对象

String jsonData = "{'name':'刘力','age':19}";
Person person = gson.fromJson(jsonData, Person.class);
System.out.println(person.getName() + ", " + person.getAge());
  • 打印结果: 刘力, 19

四、 gson把List对象解析成Json格式:

Gson gson = new Gson();
List<Person> persons = new ArrayList<Person>();
for (int i = 0; i < 2; i++) {
Person p = new Person();
p.setName("name" + i);
p.setAge(i * 5);
persons.add(p);
}
String str = gson.toJson(persons);
System.out.println(str);
  • 打印结果: [{"name":"name0","age":0},{"name":"name1","age":5}]

五、 gson把Json格式解析成List对象:

Gson gson = new Gson();
String str = "[{'name':'linux','age':10},{'name':'huhx','age':22}]";
List<Person> ps = gson.fromJson(str, new TypeToken<List<Person>>(){}.getType());
for (int i = 0; i < ps.size(); i++) {
Person person = ps.get(i);
System.out.print("name: " + person.getName() + " age: " + person.getAge());
}
  • 打印结果:name: linux age: 10 name: huhx age: 22

JSON的使用实例

现在我们开始一个andriod客户端到web服务器的请求响应过程的实用案例,这里为了方便,我们把重要的代码全部贴出来:

流程: android发送post请求到服务器,服务器返回Json数据给客户端。android解析json数据并使用。

在android客户端:

一、 在AndroidManifest.xml中加入网络权限的声明:

<uses-permission android:name="android.permission.INTERNET"/>

二、 在MainActivity中加入一个事件,去发送请求:

// 发送请求
public void jsonTest(View view) {
sendRequestWithHttpURLConnection();
}

三、 sendRequestWithHttpURLConnection是具体的发送请求的方法:

  • 首先我们是开启线程去发起请求的,请求地址是一个Servlet用作对数据的处理: 192.168.248.103是服务器的地址, http://192.168.248.103:8080/ListenerTest1/JsonServlet
  • 设置一些connection的参数,发送get请求,并且携带数据username=huhx,接收到数据用handler的方法处理信息!
private void sendRequestWithHttpURLConnection() {
// 开启线程来发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
URL url = new URL("http://192.168.248.103:8080/ListenerTest1/JsonServlet?username=huhx");
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.setRequestMethod("GET"); // 如果服务器成功响应
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream in = connection.getInputStream();
// 下面对获取到的输入流进行读取
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
} Message message = new Message();
message.what = SHOW_RESPONSE;
message.obj = response.toString();
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}

四、 定义一个Handler,用于消息的接收处理:

public static final int SHOW_RESPONSE = 0; // MainActivity中的全局变量
private final static String TAG = "Main2Activity"; // MainActivity中的全局变量 private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE:
String response = (String) msg.obj;
jsonParseStr(response);
}
}
};

五、 用JsonObject做json的数据解析处理:

// 得到返回数据,解析json数据
private void jsonParseStr(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String name = (String) jsonObject.get("name");
int age = (int) jsonObject.get("age");
Log.i(TAG, "name: " + name + ", age: " + age);
} catch (JSONException e) {
e.printStackTrace();
}
}
  • 打印结果:  name: huhx, age: 22

在web服务器端:

一、 JsonServlet的doGet方法,处理android客户端的请求:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String str = request.getParameter("username");
System.out.println(str);
Person person = new Person();
person.setAge(22);
person.setName("huhx"); Gson gson = new Gson();
String jsonStr = gson.toJson(person);
response.getWriter().write(jsonStr);
}
  • 打印结果: huhx

友情链接

android基础---->JSON数据的解析的更多相关文章

  1. android基础---->XMl数据的解析

    在网络上传输数据时最常用的格式有两种,XML和JSON,下面首先学一下如何解析XML格式的数据,JSON的解析可以参见我的博客(android基础---->JSON数据的解析).解析XML 格式 ...

  2. Android 之 json数据的解析(jsonReader)

    json数据的解析相对而言,还是比较容易的,实现的代码也十分简单.这里用的是jsonReade方法来进行json数据解析. 1.在解析之前,大家需要知道什么是json数据. json数据存储的对象是无 ...

  3. android实现json数据的解析和把数据转换成json格式的字符串

    利用android sdk里面的 JSONObject和JSONArray把集合或者普通数据,转换成json格式的字符串 JSONObject和JSONArray解析json格式的字符串为集合或者一般 ...

  4. Android 实现Json数据解析,并进行应用!

    从网站上获取数据然后再客户端进行解析是常见的数据交互.下面是常用的一些接口网址: webservice工厂接口 http://www.36wu.com 快递查询接口http://webservice. ...

  5. Android系列---JSON数据解析

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  6. Android 之JSON数据解析

    (以下基本都是郭霖大神<第一行代码>中的知识) JSON数据与xml相比,优势在于体积更小,传输所需的流量少.但是缺点也很明显,就是语义性较差. 下面是一组JSON格式的数据. [{&qu ...

  7. Android关于JSON数据解析

    一.什么是json json(Javascript Object Notation)是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比较的复杂,而且需要编写大段的代码,所以 ...

  8. iOS开发网络篇—JSON数据的解析

    iOS开发网络篇—JSON数据的解析 iOS开发网络篇—JSON介绍 一.什么是JSON JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式 ...

  9. HttpURLConnection从网上获取Json数据并解析详解

    HttpURLConnection从网上获取Json数据并解析 1.HttpURLConnection请求数据的步骤 (1)构造一个URL接口地址: URL url = new URL("h ...

随机推荐

  1. 【LeetCode】Power of Two

    问题描写叙述 Given an integer, write a function to determine if it is a power of two. 意:推断一个数是否是2的n次幂 算法思想 ...

  2. [ay原创作品]用wpf写了个模仿36Kr网站登录背景的效果

    这里我借鉴了,上周比较火的一个前端文章,人家用js去写的,地址 自己用wpf也写了一个,但是它的  粒子比较,然后连线算法真的很差,他创建了一个加入鼠标点的集合,2个集合进行比较,并且粒子会向鼠标靠近 ...

  3. Spark RDD解密

    1.  基于数据集的处理: 从物理存储上加载数据,然后操作数据,然后写入数据到物理设备; 基于数据集的操作不适应的场景: 不适合于大量的迭代: 不适合交互式查询:每次查询都需要对磁盘进行交互. 基于数 ...

  4. 40页PPT勾画“互联网颠覆性思维”----诠释互联网思维

    本文PPT内容涉及移动互联网的三个分支——移动电商.在线教育和新媒体. 不同领域一直是可以相互借鉴.相互渗透.相互学习的,在盈利模式和思维方式上有很多是共通的.  

  5. ASP.NET MVC路由规则

    1 是从上往下寻找路由规则的 2 如果上面的匹配了,则下面的不会匹配 3 假如域名是www.startpress.cn 路由规则是 routes.MapRoute( name: "Defau ...

  6. LoadRunner11.52发布,全新的VTS

    LoadRunner11.52发布,全新的VTShttp://automationqa.com/forum.php?mod=viewthread&tid=2252&fromuid=2 ...

  7. Linux RPM 命令参数使用详解

    rpm 执行安装包二进制包(Binary)以及源代码包(Source)两种.二进制包可以直接安装在计算机中,而源代码包将会由 RPM自动编译.安装.源代码包经常以src.rpm作为后缀名. 常用命令组 ...

  8. ZooKeeper与Curator注册和监控

    Curator提供了对zookeeper客户端的封装,并监控连接状态和会话session,特别是会话session过期后,curator能够重新连接zookeeper,并且创建一个新的session. ...

  9. encfs创建时fuse: failed to exec fusermount: Permission denied错误解决

    今天用encfs创建加密文件夹时碰到提示错误fuse: failed to exec fusermount: Permission denied fuse failed. Common problem ...

  10. PLSQL Developer 出64位版了

    在win64环境上,一般安装oracle客户端都是64位的了,Toad 也是64位的,但是PLSQL Developer 还是32位的,只能单单为它装一个32位的oracle 客户端,现在退出64位, ...