1、什麼是jsonjavascript
json(Javascript Object Notation)是一種輕量級的數據交換格式,相比於xml這種數據交換格式來講,由於解析xml比較的複雜,並且須要編寫大段的代碼,因此客戶端和服 務器的數據交換格式每每經過json來進行交換。尤爲是對於web開發來講,json數據格式在客戶端直接能夠經過javascript來進行解析。html
json一共有兩種數據結構,一種是以 (key/value)對形式存在的無序的jsonObject對象,一個對象以「{」(左花括號)開始,「}」(右花括號)結束。每一個「名稱」後跟一個「:」(冒號);「‘名稱/值’ 對」之間使用「,」(逗號)分隔。java
例如:{"name": "xiaoluo"}, 這就是一個最簡單的json對象,對於這種數據格式,key值必需要是string類型,而對於value,則能夠是string、number、object、array等數據類型:android
另外一種數據格式就是有序的value的集合,這種形式被稱爲是jsonArray,數組是值(value)的有序集合。一個數組以「[」(左中括號)開始,「]」(右中括號)結束。值之間使用「,」(逗號)分隔。web
更多的有關json數據格式能夠參加json的官網,http://www.json.org/json-zh.htmljson
2、解析json數據格式數組
這裏將使用兩種json的解析庫來對咱們的json數據格式進行解析以及生成咱們的json數據格式。服務器
1.json-lib(http://json-lib.sourceforge.net/)網絡
使用json-lib來進行解析,咱們須要引入第三方的包,由於json-lib分爲了兩個版本,一個版本是針對於jdk1.3的,一個版本是針對於jdk1.5的,這裏咱們下載jdk1.5的這個json-lib包,其中還須要引入其餘的幾個jar包:數據結構
下載好這幾個jar包後,加入到classpath中便可。咱們來看看json-lib給咱們提供的API。
咱們最經常使用的兩個類就是 JSONObject和JSONArray這兩個類,分別表明了json對象和json數組,這兩個類都實現了 JSON 這個接口,下面咱們經過幾個小例子來看看如何將咱們常見的幾種數據格式轉換成咱們的json對象(咱們通常稱之爲JSON數據的序列化)以及再將json 對象在轉換成咱們的數據格式(稱之爲反序列化)。
①簡單的javabean的序列化和反序列化
public class Person
{
private int id;
private String name;
private String address;
public Person()
{
}
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;
}
public Person(int id, String name, String address)
{
super();
this.id = id;
this.name = name;
this.address = address;
}
@Override
public String toString()
{
return "Person [id=" + id + ", name=" + name + ", address=" + address
+ "]";
}
}
首先咱們定義一個簡單的javabean對象,而後將一個Person對象轉換成json對象,而後再將這個json對象反序列化成咱們的Person對象。
咱們先定義一個JsonTools類,這個類有兩個靜態方法,咱們能夠經過這兩個方法來獲得一個JSON類型的字符串對象,以及一個JSON對象
public class JsonTools
{
/**
* 獲得一個json類型的字符串對象
* @param key
* @param value
* @return
*/
public static String getJsonString(String key, Object value)
{
JSONObject jsonObject = new JSONObject();
//put和element都是往JSONObject對象中放入 key/value 對
// jsonObject.put(key, value);
jsonObject.element(key, value);
return jsonObject.toString();
}
/**
* 獲得一個json對象
* @param key
* @param value
* @return
*/
public static JSONObject getJsonObject(String key, Object value)
{
JSONObject jsonObject = new JSONObject();
jsonObject.put(key, value);
return jsonObject;
}
}
咱們能夠直接經過 JSONObject jsonObject = new JSONObject(); 這個方法就能夠獲得一個json對象,而後經過element()或者是put()方法來給咱們的json對象添加key/value對。咱們先來看看第 一個例子,實現一個簡單的Person對象和json對象的轉換
Person person = new Person(1, "xiaoluo", "廣州");
// 將Person對象轉換成一個json類型的字符串對象
String personString = JsonTools.getJsonString("person", person);
System.out.println(personString.toString());
咱們看看控制檯的輸出:
{"person":{"address":"廣州","id":1,"name":"xiaoluo"}}
整個外面的大括號是一個json對象,裏面有一對key/value,其中裏面的{"address":"廣州","id":1,"name":"xiaoluo"}就是咱們轉換成的json字符串對象
再來看看如何將json對象轉換成咱們的bean對象
JSONObject jsonObject = JsonTools.getJsonObject("person", person);
// 經過JSONObject的toBean方法能夠將json對象轉換成一個javabean
JSONObject personObject = jsonObject.getJSONObject("person");
Person person2 = (Person) JSONObject.toBean(personObject, Person.class);
System.out.println(person2);
Person [id=1, name=xiaoluo, address=廣州]
②轉換List<Person>類型的對象
@Test
public void testPersonsJson()
{
List<Person> persons = new ArrayList<Person>();
Person person = new Person(1, "xiaoluo", "廣州");
Person person2 = new Person(2, "android", "上海");
persons.add(person);
persons.add(person2);
String personsString = JsonTools.getJsonString("persons", persons);
System.out.println(personsString);
JSONObject jsonObject = JsonTools.getJsonObject("persons", persons);
// List<Person>至關於一個JSONArray對象
JSONArray personsArray = (JSONArray)jsonObject.getJSONArray("persons");
List<Person> persons2 = (List<Person>) personsArray.toCollection(personsArray, Person.class);
System.out.println(persons2);
}
{"persons":[{"address":"廣州","id":1,"name":"xiaoluo"},{"address":"上海","id":2,"name":"android"}]}
[Person [id=1, name=xiaoluo, address=廣州], Person [id=2, name=android, address=上海]]
③List<Map<String, String>>類型的json對象轉換
@Test
public void testMapJson()
{
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> map1 = new HashMap<String, String>();
map1.put("id", "001");
map1.put("name", "xiaoluo");
map1.put("age", "20");
Map<String, String> map2 = new HashMap<String, String>();
map2.put("id", "002");
map2.put("name", "android");
map2.put("age", "33");
list.add(map1);
list.add(map2);
String listString = JsonTools.getJsonString("list", list);
System.out.println(listString);
JSONObject jsonObject = JsonTools.getJsonObject("list", list);
JSONArray listArray = jsonObject.getJSONArray("list");
List<Map<String, String>> list2 = (List<Map<String, String>>) listArray.toCollection(listArray, Map.class);
System.out.println(list2);
}
{"list":[{"id":"001","age":"20","name":"xiaoluo"},{"id":"002","age":"33","name":"android"}]}
[{id=001, name=xiaoluo, age=20}, {id=002, name=android, age=33}]
經過上面的例子,咱們能夠了解了如何經過json-lib這個解析庫來實現javabean、List、Map等數據和json數據的互相轉換
2.gson(http://code.google.com/p/google-gson/)
下面咱們來看看Google提供的gson這個json解析庫,一樣咱們須要去下載gson這個jar包,導入到咱們的項目中
使用gson,咱們能夠很是輕鬆的實現數據對象和json對象的相互轉化,其中咱們最經常使用的就是兩個方法,一個是fromJSON(),將json 對象轉換成咱們須要的數據對象,另外一個是toJSON(),這個就是將咱們的數據對象轉換成json對象。下面咱們也經過一個綜合的例子來看看gson的 使用方法:
public class JsonService
{
public Person getPerson()
{
Person person = new Person(1, "xiaoluo", "廣州");
return person;
}
public List<Person> getPersons()
{
List<Person> persons = new ArrayList<Person>();
Person person = new Person(1, "xiaoluo", "廣州");
Person person2 = new Person(2, "android", "上海");
persons.add(person);
persons.add(person2);
return persons;
}
public List<String> getString()
{
List<String> list = new ArrayList<String>();
list.add("廣州");
list.add("上海");
list.add("北京");
return list;
}
public List<Map<String, String>> getMapList()
{
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> map1 = new HashMap<String, String>();
map1.put("id", "001");
map1.put("name", "xiaoluo");
map1.put("age", "20");
Map<String, String> map2 = new HashMap<String, String>();
map2.put("id", "002");
map2.put("name", "android");
map2.put("age", "33");
list.add(map1);
list.add(map2);
return list;
}
}
public static void main(String[] args)
{
Gson gson = new Gson();
JsonService jsonService = new JsonService();
Person person = jsonService.getPerson();
System.out.println("person: " + gson.toJson(person));
// 對於Object類型,使用 fromJson(String, Class)方法來將Json對象轉換成Java對象
Person person2 = gson.fromJson(gson.toJson(person), Person.class);
System.out.println(person2);
System.out.println("------------------------------------------------");
List<Person> persons = jsonService.getPersons();
System.out.println("persons: " + gson.toJson(persons));
/*
* 對於泛型對象,使用fromJson(String, Type)方法來將Json對象轉換成對應的泛型對象
* new TypeToken<>(){}.getType()方法
*/
List<Person> persons2 = gson.fromJson(gson.toJson(persons), new TypeToken<List<Person>>(){}.getType());
System.out.println(persons2);
System.out.println("------------------------------------------------");
List<String> list = jsonService.getString();
System.out.println("String---->" + gson.toJson(list));
List<String> list2 = gson.fromJson(gson.toJson(list), new TypeToken<List<String>>(){}.getType());
System.out.println("list2---->" + list2);
System.out.println("------------------------------------------------");
List<Map<String, String>> listMap = jsonService.getMapList();
System.out.println("Map---->" + gson.toJson(listMap));
List<Map<String, String>> listMap2 = gson.fromJson(gson.toJson(listMap), new TypeToken<List<Map<String, String>>>(){}.getType());
System.out.println("listMap2---->" + listMap2);
System.out.println("------------------------------------------------");
}
看看控制檯的輸出:
person: {"id":1,"name":"xiaoluo","address":"廣州"}
Person [id=1, name=xiaoluo, address=廣州]
------------------------------------------------
persons: [{"id":1,"name":"xiaoluo","address":"廣州"},{"id":2,"name":"android","address":"上海"}]
[Person [id=1, name=xiaoluo, address=廣州], Person [id=2, name=android, address=上海]]
------------------------------------------------
String---->["廣州","上海","北京"]
list2---->[廣州, 上海, 北京]
------------------------------------------------
Map---->[{"id":"001","age":"20","name":"xiaoluo"},{"id":"002","age":"33","name":"android"}]
listMap2---->[{id=001, age=20, name=xiaoluo}, {id=002, age=33, name=android}]
------------------------------------------------
3、在Android客戶端解析服務器端的json數據
下面咱們來完成一個綜合的例子,Android客戶端經過一個AsyncTask異步任務請求服務器端的某些數據,而後在解析完這些數據後,將獲得的數據內容更新到咱們的Spinner這個UI控件當中。
咱們首先來看下服務器端的代碼:
@WebServlet("/CityServlet")
public class CityServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
public CityServlet()
{
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
this.doPost(request, response);
}
protected 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 writer = response.getWriter();
String type = request.getParameter("type");
if("json".equals(type))
{
List<String> cities = new ArrayList<String>();
cities.add("廣州");
cities.add("上海");
cities.add("北京");
cities.add("湖南");
Map<String, List<String>> map = new HashMap<String, List<String>>();
map.put("cities", cities);
String citiesString = JSON.toJSONString(map);
writer.println(citiesString);
}
writer.flush();
writer.close();
}
}
若是客戶端請求的參數是type=json,則響應給客戶端一個json數據格式
接着來看看客戶端的代碼,首先看看客戶端的佈局文件,其實就是一個按鈕和一個Spinner控件,當點擊按鈕後,經過http協議請求服務器端的數據,而後在接收到後再更新咱們的Spinner控件的數據
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="64dp"
android:layout_marginTop="64dp"
android:textSize="20sp"
android:text="城市" />
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/textView1"
android:layout_toRightOf="@id/textView1"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/spinner"
android:layout_marginLeft="22dp"
android:layout_marginTop="130dp"
android:text="加載數據" />
</RelativeLayout>
在Android客戶端寫一個解析json數據格式的類:
public class JsonUtils
{
/**
* @param citiesString 從服務器端獲得的JSON字符串數據
* @return 解析JSON字符串數據,放入List當中
*/
public static List<String> parseCities(String citiesString)
{
List<String> cities = new ArrayList<String>();
try
{
JSONObject jsonObject = new JSONObject(citiesString);
JSONArray jsonArray = jsonObject.getJSONArray("cities");
for(int i = 0; i < jsonArray.length(); i++)
{
cities.add(jsonArray.getString(i));
}
}
catch (Exception e)
{
e.printStackTrace();
}
return cities;
}
}
固然咱們的HttpUtils類也不可少:
public class HttpUtils
{
/**
* @param path 請求的服務器URL地址
* @param encode 編碼格式
* @return 將服務器端返回的數據轉換成String
*/
public static String sendPostMessage(String path, String encode)
{
String result = "";
HttpClient httpClient = new DefaultHttpClient();
try
{
HttpPost httpPost = new HttpPost(path);
HttpResponse httpResponse = httpClient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
HttpEntity httpEntity = httpResponse.getEntity();
if(httpEntity != null)
{
result = EntityUtils.toString(httpEntity, encode);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
httpClient.getConnectionManager().shutdown();
}
return result;
}
}
最後來看看咱們的MainActivity類:
public class MainActivity extends Activity
{
private Spinner spinner;
private Button button;
private ArrayAdapter<String> adapter;
private ProgressDialog dialog;
private final String CITY_PATH_JSON = "http://172.25.152.34:8080/httptest/CityServlet?type=json";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner = (Spinner)findViewById(R.id.spinner);
button = (Button)findViewById(R.id.button);
dialog = new ProgressDialog(MainActivity.this);
button.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
dialog.setTitle("提示信息");
dialog.setMessage("loading......");
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
new MyAsyncTask().execute(CITY_PATH_JSON);
}
});
}
public class MyAsyncTask extends AsyncTask<String, Void, List<String>>
{
@Override
protected void onPreExecute()
{
dialog.show();
}
@Override
protected List<String> doInBackground(String... params)
{
List<String> cities = new ArrayList<String>();
String citiesString = HttpUtils.sendPostMessage(params[0], "utf-8");
// 解析服務器端的json數據
cities = JsonUtils.parseCities(citiesString);return cities;
}
@Override
protected void onPostExecute(List<String> result)
{
adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_item, result);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
dialog.dismiss();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
固然別往了開啓咱們的網絡受權
<uses-permission android:name="android.permission.INTERNET"/>
最後咱們來看看效果圖:
這樣咱們就完成了客戶端與服務器端經過json來進行數據的交換