1、json定义
一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。
2、表示格式
(1)名称 / 值对
按照最简单的形式,可以用下面这样的 JSON 表示”名称 / 值对”:
{ “firstName”: “Brett” }
这个示例非常基本,而且实际上比等效的纯文本”名称 / 值对”占用更多的空间:
firstName=Brett
但是,当将多个”名称 / 值对”串在一起时,JSON 就会体现出它的价值了。首先,可以创建包含多个”名称 / 值对”的 记录,比如:
{ “firstName”: “Brett”, “lastName”:”McLaughlin”, “email”: “aaaa” }
从语法方面来看,这与”名称 / 值对”相比并没有很大的优势,但是在这种情况下 JSON 更容易使用,而且可读性更好。例如,它明确地表示以上三个值都是同一记录的一部分;花括号使这些值有了某种联系。
(2)表示数组
当需要表示一组值时,JSON 不但能够提高可读性,而且可以减少复杂性。例如,假设您希望表示一个人名列表。在XML中,需要许多开始标记和结束标记;如果使用典型的名称 / 值对(就像在本系列前面文章中看到的那种名称 / 值对),那么必须建立一种专有的数据格式,或者将键名称修改为 person1-firstName这样的形式。
如果使用 JSON,就只需将多个带花括号的记录分组在一起:
{ “people”: [
{ “firstName”: “Brett”, “lastName”:”McLaughlin”, “email”: “aaaa” },
{ “firstName”: “Jason”, “lastName”:”Hunter”, “email”: “bbbb”},
{ “firstName”: “Elliotte”, “lastName”:”Harold”, “email”: “cccc” }
]}
这不难理解。在这个示例中,只有一个名为 people的变量,值是包含三个条目的数组,每个条目是一个人的记录,其中包含名、姓和电子邮件地址。上面的示例演示如何用括号将记录组合成一个值。当然,可以使用相同的语法表示多个值(每个值包含多个记录):
{ “programmers”: [
{ “firstName”: “Brett”, “lastName”:”McLaughlin”, “email”: “aaaa” },
{ “firstName”: “Jason”, “lastName”:”Hunter”, “email”: “bbbb” },
{ “firstName”: “Elliotte”, “lastName”:”Harold”, “email”: “cccc” }
],
“authors”: [
{ “firstName”: “Isaac”, “lastName”: “Asimov”, “genre”: “science fiction” },
{ “firstName”: “Tad”, “lastName”: “Williams”, “genre”: “fantasy” },
{ “firstName”: “Frank”, “lastName”: “Peretti”, “genre”: “christian fiction” }
],
“musicians”: [
{ “firstName”: “Eric”, “lastName”: “Clapton”, “instrument”: “guitar” },
{ “firstName”: “Sergei”, “lastName”: “Rachmaninoff”, “instrument”: “piano” }
] }
这里最值得注意的是,能够表示多个值,每个值进而包含多个值。但是还应该注意,在不同的主条目(programmers、authors 和 musicians)之间,记录中实际的名称 / 值对可以不一样。JSON 是完全动态的,允许在 JSON 结构的中间改变表示数据的方式。
json解析代码示例
// 普通Json数据解析
private void parseJson(String strResult) {
try {
JSONObject jsonObj = new JSONObject(strResult).getJSONObject("singer");
int id = jsonObj.getInt("id");
String name = jsonObj.getString("name");
String gender = jsonObj.getString("gender");
tvJson.setText("ID号"+id + ", 姓名:" + name + ",性别:" + gender);
} catch (JSONException e) {
System.out.println("Json parse error");
e.printStackTrace();
}
}
jsonData是请求网络得到的json数据,网络连接部分没有在此给出。
private void parseJSONWithJSONObject(String jsonData){
//解析多个json数据
try {
JSONArray jsonArray = new JSONArray(jsonData);
for(int i = 0;i < jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");
Log.d("MainActivity", "id is" + id);
Log.d("MainActivity", "name is" + name);
Log.d("MainActivity", "version is" + version);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
下面给出一个完整的JSONObject解析json数据的示例,包括网络请求部分,json解析部分,最后把解析得到的数据使用handler设置到textview上。
package com.example.jsontest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.media.Image;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener{
public static final int SHOW_RESPONSE = 0;
private Button mButtonJson;
private TextView mTextView;
private Handler handler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE:
String response = (String) msg.obj;
mTextView.setText(response);
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButtonJson = (Button) findViewById(R.id.button_json);
mTextView = (TextView) findViewById(R.id.textview);
mButtonJson.setOnClickListener(this);
}
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch (view.getId()) {
case R.id.button_json:
sendRequestWithHttpClient();
break;
default:
break;
}
}
/**
* 网络请求部分
*/
private void sendRequestWithHttpClient(){
new Thread(new Runnable() {
@Override
public void run() {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://www.weather.com.cn/data/cityinfo/101120101.html");
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity, "utf-8");
parseJSONWithJSONObject(MainActivity.this, response);
}else{
Toast.makeText(MainActivity.this, "查询失败", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
/**
* 使用JSONObject解析得到是数据
* @param context 上下文
* @param jsonData 要解析的json数据
*/
private void parseJSONWithJSONObject(Context context,String jsonData){
try {
JSONObject jsonObject = new JSONObject(jsonData);
JSONObject weatherInfo = jsonObject.getJSONObject("weatherinfo");
// JSONObject img1 = weatherInfo.getJSONObject("n0.gif");
String city = weatherInfo.getString("city");
String cityid = weatherInfo.getString("cityid");
String temp1 = weatherInfo.getString("temp1");
String temp2 = weatherInfo.getString("temp2");
String weather = weatherInfo.getString("weather");
String ptime = weatherInfo.getString("ptime");
String data = context.getString(R.string.city)+city+"\n"
+context.getString(R.string.cityid)+cityid+"\n"
+context.getString(R.string.temp1)+temp1+"\n"
+context.getString(R.string.temp2)+temp2+"\n"
+context.getString(R.string.weather)+weather+"\n"
+context.getString(R.string.ptime)+ptime;
Message message = new Message();
message.what = SHOW_RESPONSE;
message.obj = data;
handler.sendMessage(message);
Log.d("MainActivity", city);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
使用时需要倒包gson.jar
GSON可以讲一段json格式的字符串自动映射成一个对象,从而不需要我们再手动编写代码进行解析了。
如下一段json格式的数据:
{“name”:”Tom”,”age”:20}
定义一个Person类,加入name和age两个字段,调用下面代码将json数据自动解析成一个person对象
Gson gson = new Gson();
Person person = gson.fromJson(jsonData,Person.class);
解析一段json数组,需要借助TypeToken将期望解析的数据类型传入到fromJson()方法中。
public void parseJSONWithGSON(String jsonData){
Gson gson = new Gson();
List applist = gson.fromJson(jsonData, new TypeToken>().getType());
for(App app : applist){
Log.d("MainActivity","id is"+app.getId());
Log.d("MainActivity","name is"+app.getName());
Log.d("MainActivity","version is"+app.getVersion());
}
}
存放数据的类
public void parseJSONWithGSON(String jsonData){
Gson gson = new Gson();
List applist = gson.fromJson(jsonData, new TypeToken>().getType());
for(App app : applist){
Log.d("MainActivity","id is"+app.getId());
Log.d("MainActivity","name is"+app.getName());
Log.d("MainActivity","version is"+app.getVersion());
}
}