跳到主要內容

GSON基礎教學

GSON 前言

JSON是很常見的資料交換格式,在JAVA領域常用處理JSON的函式庫:GSON、FastXML和JSON-B,本章節會以GSON為主,學習目標如下

  • JSON格式說明
  • GSON 套件函式
  • GSON: 物件轉換JSON字串
  • GSON: JSON字串轉換物件

JSON 格式說明

JSON全名為JavaScript Object Notation,它是一種輕量級的資料交換格式,會大為流行的理由,主要是他比傳統用xml更輕巧且容易處理,JSON表達方式物件會用大括弧{},陣列則是用中括號[]。
用JSON字串來表達Employee的物件內容,由JSON字串可以知道物件name、age、sex和salary屬性。

JSON表示員工資料方式:
{“name”:”Jack Bryant”, “age”:18, “sex”:”M”,”salary”:3500.00}

JSON陣列表示方式:
跟我們使用JAVA的陣列方式類似,內容值可以是數字’、文字、布林、陣列、物件、null等等。
範例:
字串: [“紅”、”橙”、”黃”、”綠”、”青”、”藍”、”紫”}
布林: [true, true, false, false, true, true]

GSON 套件函式

Gson為google所發布的函式庫,主要將物件與json字串之間的轉換時方便使用。當我們將JAVA物件轉換成JSON字串稱為序列化,JSON字串轉換至JAVA物件稱為反序列化

enter image description here

GSON: 物件轉換JSON字串

有了JSON基本概念後,我們進入本章重點,首先我們需要建立員工類別(Employee),定義如下

物件 屬性
員工類別 Employee name 名字
age 年紀
sex 性別
salary 薪水
/**
 *  name:員工類別
 */
public class Employee implements Serializable {
    //constructor
    public  Employee(String name, double salary){
        this.name = name;
        this.salary = salary;
    }

    // employ's attribute
    private String name ;
    private int age ;
    private String sex;
    private double salary ;

    //setter and getter
    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;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer() ;
        sb.append("") ;
        sb.append("name:"+name) ;
        sb.append("age:"+age) ;
        sb.append("sex:"+sex) ;
        sb.append("salary:"+salary) ;
        sb.append("") ;
        return sb.toString() ;
    }
   }

完成員工類別後,實際建立一個employee01 的物件,在使用Gson之前需要宣告Gson建構子,範例不管單數還是多數的物件,都是利用同一個toJson()方法來完成序列化轉成JSON字串,所使用起來相當方便。由結果可以發現兩件事情,一、我們發現單數和多數Json字串不同,多數物件顯示會有中括號[物件1、物件2]包括,但是單數沒有。二、Json字串缺少顯示sex屬性值,其將sex屬性列印出來後發現為null值,表示Gson會預先將屬性值為null的預先過濾掉後,才轉成JSON字串。這種方式並不會影響之後反序列處理。後續會有更詳細的Gson字串處理介紹

     /**
 * name : 員工轉json字串測試
 */
public class EmployeeTest {

    public static  void main(String[] arg){
               //單筆
        Employee employee01 = new Employee("bryan",30000);
        Employee employee02 = new Employee("joe",31000);
        employee02.setSex("N");
        Gson gson =  new Gson();
        String jsonStr1 = gson.toJson(employee01);
        String jsonStr2 = gson.toJson(employee01,Employee.class);
        System.out.println("jsonStr1:"+jsonStr1);
        System.out.println("jsonStr2:"+jsonStr2);

        //多筆
        List list = new ArrayList();
        list.add(employee01) ;
        list.add(employee02) ;
        String jsonStr3 = gson.toJson(list);
        System.out.println("jsonStr3:"+jsonStr3);

    }
}

結果:
jsonStr1:{“name”:”bryan”,”age”:0,”salary”:30000.0}
jsonStr2:{“name”:”bryan”,”age”:0,”salary”:30000.0}
jsonStr3:[{“name”:”bryan”,”age”:0,”salary”:30000.0},{“name”:”joe”,”age”:0,”sex”:”N”,”salary”:31000.0}]

物件關係表達

接下來我們將物件關係也加入,看Gson是否可以順利轉換成正確JSON字串,首先我們新增兩個物件:書明細(Book)和借書訂單(Order),之間的關係為員工借書會點選借書訂單系統,去挑選他的書明細,該系統會記錄該員工的姓名以及他點選書單的明細。

物件 屬性
書明細 Book bid 書單號
title書名稱
author 作者
借書訂單 Order orderId 訂單編號
employName 員工名稱
date 日期
bookList 書明細資料
/**
 * name : 書明細
 */
public class Book {
    private String bid;
    private String title;
    private String author;

    public Book(String bid, String title, String author)  {
        this.bid = bid ;
        this.title = title ;
        this.author = author ;
    }
    //setter and getter
    public String getBId() {
        return bid;
    }

    public void setBId(String id) {
        this.bid = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer() ;
        sb.append("") ;
        sb.append("bid:"+bid) ;
        sb.append("title:"+title) ;
        sb.append("author:"+author) ;
        sb.append("") ;
        return sb.toString() ;
    }

}

/**
 * name : 借書訂單
 */
public class Order {
    private String orderId;
    private String employName;
    private Date date;
    private List bookList;
    public Order(String orderId, String employName, Date date,
                 List bookList) {
        super();
        this.orderId = orderId;
        this.employName = employName;
        this.date = date;
        this.bookList = bookList;
    }

    //setter and getter
    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String getEmployName() {
        return employName;
    }

    public void setEmployName(String employName) {
        this.employName = employName;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public List getBookList() {
        return bookList;
    }

    public void setBookList(ArrayList bookList) {
        this.bookList = bookList;
    }

    public void show() {
        System.out.println("Order information:");
        System.out.println("orderId = " + orderId + "; employName = " + employName
                + "; date = " + date);
        System.out.println("Details: ");
        System.out.println(bookList.toString());
    }
}

employee01藉兩本書分別編號為B0001和B0002,這兩本書,我們把它加入oreder建構子中,再由Gson轉換成JSON字串出來,由結果顯示可以知道該訂單借了幾本書和是哪位員工借走。

/**
 * name : 借書訂單轉json字串測試
 */
public class OrderTest {

    public static  void main(String[] arg){
        //單筆
        Employee employee01 = new Employee("bryan",30000);
        Employee employee02 = new Employee("joe",31000);
        Book book01 = new Book("B0001","水滸傳","施耐庵 ") ;
        Book book02 = new Book("B0002","西遊記","吳承恩 ") ;
        Book book03 = new Book("B0003","三國演義","羅貫中 ") ;
        Book book04 = new Book("B0004","紅樓夢","曹雪芹 ") ;
        List bList = new ArrayList

JSON字串轉換物件

之前員工建立的Json字串,現在介紹如何用Gson來反序列Employee物件,有範例可以知道,Gson幾行就可以將JSON轉成物件化,用起來相當方便。

範例: JSON字串: {“name”:”bryan”,”age”:0,”salary”:30000.0}

/**
 * name: Json to Object 反序列範例
 */
public class EmployeeSTest {

    public static void main(String[] ags){
        Gson gson = new Gson();
        String employ_json = "{\"name\":\"bryan\",\"age\":0,\"salary\":30000.0}" ;
        Employee employee01 =  gson.fromJson(employ_json, Employee.class) ;
        System.out.println(employee01.toString());

    }
}

再來我們試看看List串列看看,是否可以也是跟上面宣告多數的物件相同,複數物件反序列比較麻煩一點,因為反序列需要告訴預先要轉換哪種類別,利用new TypeToken的方式來取得類別的類型,再使用fromJson方法轉回List<Employee>類型。
問題延伸: 但如果遇到泛型要如何解決?

Json字串: [{“name”:”bryan”,”age”:0,”salary”:30000.0},{“name”:”joe”,”age”:0,”sex”:”N”,”salary”:31000.0}]

/**
 * name: Json to Object 反序列範例
 */
public class EmployeeSTest {

    public static void main(String[] ags){
        Gson gson = new Gson();
        String employ_json = "{\"name\":\"bryan\",\"age\":0,\"salary\":30000.0}" ;
        Employee employee01 =  gson.fromJson(employ_json, Employee.class) ;
        System.out.println(employee01.toString());
        System.out.println("=========================List===========================");
        String employs_json = "[{\"name\":\"bryan\",\"age\":0,\"salary\":30000.0},{\"name\":\"joe\",\"age\":0,\"sex\":\"N\",\"salary\":31000.0}]";
        Type collectionType = new TypeToken

參考資料

  1. https://bng86.gitbooks.io/android-third-party-/content/gson.html
  2. http://j796160836.pixnet.net/blog/post/30530326-%E7%9E%AD%E8%A7%A3json%E6%A0%BC%E5%BC%8F
  3. http://blog.csdn.net/zzp_403184692/article/details/8266575

留言

這個網誌中的熱門文章

PHP與Python搭配

今天介紹如何利用php網頁呼叫目錄下的python程式工作或是資料交換,本人整理的方法有兩種 使用system()、exec()、shell_exec()呼叫程式 (1) string system ( string return_var ] ) 參考網址 官網解釋system()用來執行外部命令,返回為印出的結果,passthru()跟system()類似但是它不會返回結果。 範例1. 利用system執行ls指定並顯示在網頁上,無法使用變數保留ls的結果 檔案名稱: psystem.php $jsondata= system("ls -al", $result); 結果: (2) exec() : string exec ( string output [, int &$return_var ]] ) 參考網址 範例2. 利用exec執行python程式並可以回傳json格式給前端網頁做處理並顯示。我們ptopy.php就是可以看到callpy()為執行py的函式,它執行完pyEx01.py會將結果給$jsondata變數,做後面json解析。 檔案名稱: ptopy.php function callpy() { $jsondata= exec("/usr/bin/python pyEx01.py"); return $jsondata ; } $jsondata= callpy(); echo $jsondata ; echo " " ; $obj = json_decode($jsondata) ; echo "name:".$obj-> { 'name'} .',' ; echo "id:".$obj-> { 'id'} ; 檔案名稱: pyEx01.py import sys ...

Python AI-問題集

Python AI-問題集 問題集 Jupyter Notebook執行ipywidgets會出現kernel死掉的錯誤發生(The kernel appears to have died) 解決方法 (1) 根據log檔來判斷問題: 例如:log訊息出現OMP: Error #15: Initializing libiomp5.dylib, but found libiomp5.dylib already initialized. (2) 根據問題關鍵字找出問題所在: 利用google查詢所遭遇到的問題,例如我把上面的問題上google查詢可以找到這篇的解法 https://blog.csdn.net/bingjianIT/article/details/86182096 (3)實作解法: 我實作下面解法後,就可以順利執行手寫辨識的程式. //在Python宣告時加入 import os os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" 參考 https://blog.csdn.net/bingjianIT/article/details/86182096