JSON快速入門(Java版)
1.JSON
JSON簡介: 是一種輕量級的資料交換格式。它基於 ECMAScript (歐洲計算機協會制定的js規範)的一個子集,採用完全獨立於程式語言的文字格式來儲存和表示資料。簡潔和清晰的層次結構使得 JSON 成為理想的資料交換語言,易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提升網路傳輸效率。
JSON:是行業內使用最為廣泛的資料傳輸格式。
(呼叫服務端)API時會使用JSON作為返回格式。
JSON是資料儲存的一種格式,格式簡單,易於讀寫,格式都是壓縮的,佔用頻寬小。
最初來自JS,後來幾乎每種常用語言都有處理JSON的API,支援多種伺服器端語言,便於伺服器端的解析。
JSON缺點:要求字符集必須是Unicode,受約束性強。
①JSON是一種與開發語言無關的、輕量級的資料格式。全稱為JavaScript Object Notation。
優點:易於人的閱讀和編寫,易於程式解析與生產。
②例項:
{ }:標識一個物件(即結構體)。
{ }中包含鍵值對結構,key必須是String型別,value為任何基本型別或資料結構。
[ ]:代表陣列Array,並用逗號,來分隔元素。
基本型別:String、number、true、false、null。
ps:(沒有浮點整數、正負數...之分,在寫java程式碼時,JSONObject的put方法會自動區分不同數字格式。)
這是一種JSONObject原生資料格式到java資料格式的對映關係。
元素可以是任意型別。
標準JSON不支援任何形式註釋。
json沒有日期資料格式。
③org.json包的使用:
a.生成JSON物件:
package json;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
/**
* @Auther: wjy
* @Date: 2018/10/10 16:34
* @Description: 使用JSONObject相關構建JSON物件。
*/
public class jsonTest {
public static void main(String[] args) {
jsonobject();// 使用JSONObject構建JSON物件。
createJsonByMap();// 通過HashMap資料結構構建JSON物件。
createjavaBean();// 通過Javabean來構建JSON物件。
}
private static void jsonobject() {
JSONObject messi = new JSONObject();// 構建JSON物件。
Object NULL = null;
try {
messi.put("name","messi");
messi.put("name","梅西");// 替代性,二次賦值會代替第一次賦值。
messi.put("age",31.4);
messi.put("birthday","1987-06-24");
messi.put("school","Barcelona");
messi.put("major",new String[]{"player","star"});// 也可以使用集合裝陣列。
messi.put("car",true);
messi.put("house",true);
messi.put("daughter",NULL);// 直接複製null會產生二義性。
messi.put("girlfriend","安東內拉");
messi.put("comment","love him!!");
System.out.println(messi/*或messi.toString()*/);// 不會按照插入資料順序顯示。
/*{"birthday":"1987-06-24","girlfriend":"安東內拉","major":["player","star"],"school":"Barcelona","car":true,"name":"梅西","comment":"love him!!","house":true,"age":31.4}*/
} catch (JSONException e) {
e.printStackTrace();
}
}
private static void createJsonByMap() {
HashMap<String,Object> messi = new HashMap<String, Object>();
Object NULL = null;
messi.put("name","messi");
messi.put("name","梅西");
messi.put("age",31.4);
messi.put("birthday","1987-06-24");
messi.put("school","Barcelona");
messi.put("major",new String[]{"player","star"});
messi.put("car",true);
messi.put("house",true);
messi.put("daughter",NULL);
messi.put("girlfriend","安東內拉");
messi.put("comment","love him!!");
System.out.println(new JSONObject(messi)/*或new JSONObject(messi).toString()*/);
/*{"birthday":"1987-06-24","girlfriend":"安東內拉","major":["player","star"],"school":"Barcelona","car":true,"name":"梅西","comment":"love him!!","house":true,"daughter":null,"age":31.4}*/
// 建構函式支援傳入Map介面物件 將Map轉換為JSON。
}
private static void createjavaBean() {
beanTest messi = new beanTest();
Object NULL = null;
messi.setName("messi");
messi.setName("梅西");
messi.setAge(31.4);
messi.setBirthday("1987-06-24");
messi.setSchool("Barcelona");
messi.setMajor(new String[]{"player","star"});
messi.setCar(true);
messi.setHouse(true);
messi.setDaughter(NULL);
messi.setGirlfriend("安東內拉");
messi.setComment("love him!!");
System.out.println(new JSONObject(messi/*messi.toString()*/));// 最終的方式還是使用JSONObject。
// 但是並沒有把屬性置於JSONObject中。
/*{"birthday":"1987-06-24","girlfriend":"安東內拉","major":["player","star"],"school":"Barcelona","car":true,"name":"梅西","comment":"love him!!","daughter":null,"house":true,"age":31.4}*/
}
}
package json;
/**
* @Auther: wjy
* @Date: 2018/10/10 17:21
* @Description: JavaBean。
*/
public class beanTest {
private String name;
private double age;
private String birthday;
private String school;
private String[] major;
private Boolean car;
private Boolean house;
private String girlfriend;
private Object daugter;
private String comment;
public beanTest(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
...
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
b.解析json資料格式:通過檔案讀取/遠端API獲取資料內容,再轉換為JSONObject。
package json;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* @Auther: wjy
* @Date: 2018/10/10 18:31
* @Description: 解析json資料格式。
* JSONObject不支援使用JavaBean反解析json。
*/
public class readJsonTest {
public static void main(String[] args) throws IOException, JSONException {
File file = new File(readJsonTest.class.getResource("../messi.json").getFile());// class的方法獲取檔案。
// 快速讀取內容。
String content = FileUtils.readFileToString(file);// 讀取檔案內容。
JSONObject json = new JSONObject(content);// 將讀取內容轉換為json物件。
// bug:
// JSONArray majorArray = new JSONArray("major");// 需要JSONArray解析json陣列。
if( !json.isNull("name")) {// 通過此方法,增加程式健壯性。
System.out.println("姓名: " + json.getString("name"));
}
System.out.println("年齡: "+json.getDouble("age"));
System.out.println("生日: "+json.getString("birthday"));
System.out.println("學校: "+json.getString("school"));
// bug:
/*for(int i=0; i<majorArray.length(); i++) {
String m = majorArray.getString(i);
System.out.println("專業"+(1+i)+m);
}*/
System.out.println("有車車嗎: "+json.getBoolean("car"));
System.out.println("有房房嗎: "+json.getBoolean("house"));
System.out.println("有女朋友嗎: "+json.getString("girlfriend"));
System.out.println("有女兒嗎: "+json.getString("daughter"));
System.out.println("註釋: "+json.getString("comment"));
/*
姓名: 梅西
年齡: 31.4
生日: 1987-06-24
學校: Barcelona
有車車嗎: true
有房房嗎: true
有女朋友嗎: 安東內拉
有女兒嗎: null
註釋: love him!
*/
}
}
2.GSON
谷歌提出的,開源的第三方工具。
相比於JSONObject,功能更加強大,效能更加出色,使用方式更加簡單和便捷。
①GSON生成JSON資料:
為了改變某一確定的配置,可以使用GsonBuilder建立Gson例項,並自定義各種配置。
GsonBuilder類提供了.Create()方法,該方法返回一個Gson例項。
該Gson例項可以做任何之前已經向你展示的功能:對映任何從JSON來或者到JSON去的資料。
Gson gson = new Gson();
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
package gson;
import com.google.gson.FieldNamingStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.lang.reflect.Field;
/**
* @Auther: wjy
* @Date: 2018/10/11 10:13
* @Description: 生成Json資料。
*/
public class createJavaBean {
public static void main(String[] args) {
beanTest1 messi = new beanTest1();
Object NULL = null;
messi.setName("messi");
messi.setName("梅西");
messi.setAge(31.4);
messi.setBirthday("1987-06-24");
messi.setSchool("Barcelona");
messi.setMajor(new String[]{"player", "star"});
messi.setCar(true);
messi.setHouse(true);
messi.setDaughter(NULL);
messi.setGirlfriend("安東內拉");
messi.setComment("love him!!");
// 通過註解將name變為NAME。
// 即在構建過程中個性化。
Gson g1 = new Gson();
System.out.println(g1.toJson(messi));// 生成JSON資料。
/*{"NAME":"梅西","age":31.4,...}*/
// 通過傳入回撥引數將age變為AGE。
GsonBuilder g2 = new GsonBuilder();
g2.setFieldNamingStrategy(new FieldNamingStrategy() {
@Override
public String translateName(Field field) {
if (field.getName().equals("age")) {// key為age時,變為AGE。
return "AGE";
}
return field.getName();// 否則正常返回。
}
});
g1 = g2.create();
System.out.println(g1.toJson(messi));// 生成Json資料。
/*{"NAME":"梅西","AGE":31.4,...}*/
// 美化json格式,返回美麗的格式。
g2.setPrettyPrinting();// 美化格式。
g1 = g2.create();
System.out.println(g1.toJson(messi));// 生成Json資料。
/*{
"NAME": "梅西",
"AGE": 31.4,
"birthday": "1987-06-24",
"school": "Barcelona",
"major": [
"player",
"star"
],
"car": true,
"house": true,
"girlfriend": "安東內拉",
"comment": "love him!!"
}
*/
// 要在JavaBean中構建json時隱藏某個屬性。
// 即執行時看不到這個屬性,private transient String ignore。
messi.setIgnore("I love you!");
System.out.println(g1.toJson(messi));// 生成Json資料。
}
}
package gson;
import com.google.gson.annotations.SerializedName;
public class beanTest1 {
@SerializedName("NAME")
// 通過添加註解的方式,標識生成json格式資料的一個key。
// 將name轉換為NAME,相當於解析的時候重新命名。
// GSON有更強的靈活性。
private String name;
private double age;
private String birthday;
private String school;
private String[] major;
private Boolean car;
private Boolean house;
private String girlfriend;
private Object daughter;
private String comment;
public beanTest1(){}
private transient String ignore;
// 用這種定義方式隱藏屬性。
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
...
public String getIgnore() {
return ignore;
}
public void setIgnore(String ignore) {
this.ignore = ignore;
}
}
②GSON解析JSON資料格式:
package gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
/**
* @Auther: wjy
* @Date: 2018/10/11 20:00
* @Description: Gson解析。
*/
public class readGsonTest {
public static void main(String[] args) throws IOException {
File file = new File(readGsonTest.class.getResource("../messi.json").getFile());
// class的方法獲取檔案。
// 快速讀取內容。
String content = FileUtils.readFileToString(file);// 讀取檔案內容。
// Gson解析(帶日期轉換)
// json是不支援日期格式的,但java支援,所以在java中解析json時,
// 使用GsonBuilder的setDateFormat("yyyy-MM-dd")方法可以轉換成Date格式。
Gson g1 = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
// 即把符合這個模板格式的日期字串(json中birthday的value)轉換成Date型別(Javabean中birthday值)。
beanTest2 messi = g1.fromJson(content, beanTest2.class);
System.out.println(messi.getBirthday());
// Wed Jun 24 00:00:00 CDT 1987。
messi = g1.fromJson(content, beanTest2.class);
// Json反向解析成Javabean物件。
System.out.println(messi.toString());// [email protected]。
System.out.println(messi);// [email protected]。
System.out.println(messi.getGirlfriend());// 安東內拉。
System.out.println(messi.getAge());// 31.4。
// 將json陣列與Java中集合類無縫對接。
// 即將json中的陣列自動轉換為Javabean中的集合型別。
// 實際開發中,常用集合類代替資料,集合有更多特性,可滿足不同應用。
System.out.println(messi.getMajor());// [player, star]。
System.out.println(messi.getMajor().getClass());// class java.util.ArrayList。
}
}
package gson;
import java.util.Date;
import java.util.List;
public class beanTest2 {
private double age;
private Date birthday;
private List<String> major;
private String girlfriend;
public beanTest2(){}
public double getAge() {
return age;
}
public void setAge(double age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public List<String> getMajor() {
return major;
}
public void setMajor(List<String> major) {
this.major = major;
}
public String getGirlfriend() {
return girlfriend;
}
public void setGirlfriend(String girlfriend) {
this.girlfriend = girlfriend;
}
}
3.其他
JSON是Android SDK官方的庫。
GSON應用於服務端開發,功能更強大。
4.阿里
未完待續。