1. 程式人生 > >fastjson-1.2.21 使用例項,複雜巢狀Java物件轉json物件,複雜巢狀json物件轉對應Java物件的程式碼實現

fastjson-1.2.21 使用例項,複雜巢狀Java物件轉json物件,複雜巢狀json物件轉對應Java物件的程式碼實現

理論我就不多廢話了,直接看程式碼吧。使用的是fastjson-1.2.21版本的來實現下面程式碼的。

主要是實現複雜的巢狀的Java物件,也就是物件巢狀物件的複雜物件,轉換成json字串。然後就是反過來,把複雜的json字串轉換成對應的巢狀的Java物件。

先上工具類。如下。

package com.lxk.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * JSON 轉換
 */
public final class JsonUtils {

    /**
     * 把Java物件轉換成json字串
     *
     * @param object 待轉化為JSON字串的Java物件
     * @return json 串 or null
     */
    public static String parseObjToJson(Object object) {
        String string = null;
        try {
            //string = JSON.toJSONString(object);
            string = JSONObject.toJSONString(object);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return string;
    }

    /**
     * 將Json字串資訊轉換成對應的Java物件
     *
     * @param json json字串物件
     * @param c    對應的型別
     */
    public static <T> T parseJsonToObj(String json, Class<T> c) {
        try {
            //兩個都是可行的,起碼我測試的時候是沒問題的。
            //JSONObject jsonObject = JSONObject.parseObject(json);
            JSONObject jsonObject = JSON.parseObject(json);
            return JSON.toJavaObject(jsonObject, c);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return null;
    }
}

從程式碼中引入的包來看,真就是簡單的只是引用了com.alibaba.fastjson這個包裡面的2個類。所以,使用這個包,就很簡單,不耦合其他工具包。

上面物件轉json字串的方法還可以如下修改下。

    /**
     * 把Java物件轉換成json字串
     *
     * @param object 待轉化為JSON字串的Java物件
     * @return json 串 or null
     */
    public static <T> String parseObjToJson(T object) {
        String string = null;
        try {
            //string = JSON.toJSONString(object);
            string = JSONObject.toJSONString(object);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return string;
    }
把穿進去的Object類給換成泛型,顯得高階點點。這樣的話,2個方法都是使用的泛型啦。可以讓你寫程式碼的水平,稍微悶騷一下。這只是泛型的簡單用法。所以說只是稍微。

關於泛型,不懂的可以看下面的連結:包教包不會。

pom.xml中引入如下配置。

        <!-- json轉換很是方便的工具jar -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.21</version>
        </dependency>
非maven專案,也可以去找這個jar包:fastjson-1.2.21.jar

我給放到雲盤上,這裡分享下:連結:http://pan.baidu.com/s/1dE1CLc1 密碼:xg2c      有需要的可以直接下載使用,省的麻煩。嫌棄版本舊的也可自己找最新的。

下面是測試類。

package com.lxk.json;

import com.google.common.collect.Lists;
import com.lxk.model.Car;
import com.lxk.model.Dog;
import com.lxk.model.Student;

import java.util.List;

/**
 * 測試json和Java物件之間的轉換
 * <p>
 * Created by lxk on 2017/6/15
 */
public class TestJsonMain {
    public static void main(String[] args) {
        Student student = getStudent();
        String studentJson = JsonUtils.parseObjToJson(student);
        System.out.println(studentJson);
        Student studentFromJson = JsonUtils.parseJsonToObj(studentJson, Student.class);
        System.out.println(studentFromJson);
    }

    private static Student getStudent() {
        Dog dog1 = new Dog("大師兄的dog", true, true);
        Dog dog2 = new Dog("大師兄的dog", false, false);
        List<Dog> dogs = Lists.newArrayList();
        dogs.add(dog1);
        dogs.add(dog2);
        List<String> boys = Lists.newArrayList("tom", "jerry", "jack");
        Car car = new Car("q7", 182, dogs, boys);
        Student student = new Student();
        student.setName("Lxk");
        student.setCar(car);
        return student;
    }
}

然後就是看程式碼的執行結果。


這個乍一看,看不出來什麼,我把我用到的幾個Java bean也給放這吧,看官,別嫌棄文章太長。已經刪掉getter和setter了

先是主體類Student類

package com.lxk.model;

/**
 * Created by lxk on 2017/3/23
 */
public class Student implements Cloneable {
    private String name;
    private Car car;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", car=" + car +
                '}';
    }

    @Override
    public Student clone() {
        Student student = null;
        try {
            student = (Student) super.clone();
            if (car != null) {
                student.setCar(car.clone());
            }
        } catch (CloneNotSupportedException ignored) {
            System.out.println(ignored.getMessage());
        }
        return student;
    }
}

這個是我原來測試clone方法的使用(Java中的深淺克隆)的時候,使用的類,現在順道帶過來測試這個,也是可以的。

只要你暫時沒用到過這個clone方法,估計你也是不會去研究這個深淺克隆的,我還是附上鍊接吧。看連結:

然後就是學生的屬性Car類

package com.lxk.model;

import com.google.common.collect.Lists;

import java.util.List;

public class Car implements Cloneable, Comparable<Car> {
    private String sign;
    private int price;
    private List<Dog> myDog;
    private List<String> boys;

    public Car() {
    }

    public Car(String sign, int price) {
        this.sign = sign;
        this.price = price;
    }

    public Car(String sign, int price, List<Dog> myDog) {
        this.sign = sign;
        this.price = price;
        this.myDog = myDog;
    }

    public Car(String sign, int price, List<Dog> myDog, List<String> boys) {
        this.sign = sign;
        this.price = price;
        this.myDog = myDog;
        this.boys = boys;
    }

    @Override
    public int compareTo(Car o) {
        //同理也可以根據sign屬性排序,就不舉例啦。
        return this.getPrice() - o.getPrice();
    }

    @Override
    public String toString() {
        return "Car{" +
                "sign='" + sign + '\'' +
                ", price=" + price +
                ", myDog=" + myDog +
                ", boys=" + boys +
                '}';
    }

    @Override
    public Car clone() {
        Car car = null;
        try {
            car = (Car) super.clone();
            if (myDog != null) {
                car.setMyDog(Lists.newArrayList(myDog));
            }
            if (boys != null) {
                car.setBoys(Lists.newArrayList(boys));
            }
        } catch (CloneNotSupportedException ignored) {
            System.out.println(ignored.getMessage());
        }
        return car;
    }
}
這個也是,在測試clone,Java的深淺克隆用法的時候,使用的Javabean。順道實現了comparable介面,好像是測試集合類排序的時候使用的吧。

下面就是Dog類

package com.lxk.model;

import com.google.common.base.Objects;

/**
 * 測試boolean屬性的getter和setter
 * <p>
 * Created by lxk on 2016/12/23
 */
public class Dog {
    private String name;
    private boolean isLoyal;//是忠誠的
    private boolean alive;//活蹦亂跳的

    public Dog() {
    }

    public Dog(boolean isLoyal, boolean alive) {
        this.isLoyal = isLoyal;
        this.alive = alive;
    }

    public Dog(String name, boolean isLoyal, boolean alive) {
        this.name = name;
        this.isLoyal = isLoyal;
        this.alive = alive;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Dog)) return false;
        Dog dog = (Dog) o;
        return Objects.equal(getName(), dog.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getName());
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", isLoyal=" + isLoyal +
                ", alive=" + alive +
                '}';
    }
}
這個的測試目的,在類註釋上說了,主要是boolean型別的屬性要是以is開頭,可能自動生成getter,setter的時候,會產生一些bug。看連結:

好了,到這裡,就把使用的三個model類囉嗦完了。下面再看主程式碼執行結果吧。

先是把複雜巢狀Java物件轉換成json字串物件,對json物件稍加格式化,展示如下。

{
    "car": {
        "boys": [
            "tom",
            "jerry",
            "jack"
        ],
        "myDog": [
            {
                "alive": true,
                "loyal": true,
                "name": "大師兄的dog"
            },
            {
                "alive": false,
                "loyal": false,
                "name": "大師兄的dog"
            }
        ],
        "price": 182,
        "sign": "q7"
    },
    "name": "Lxk"
}
然後就是把這個json字串再轉乘Java物件的執行結果。也格式化下,展示如下。
Student{
    name='Lxk',
    car=Car{
        sign='q7',
        price=182,
        myDog=[
            Dog{
                name='大師兄的dog',
                isLoyal=true,
                alive=true
            },
            Dog{
                name='大師兄的dog',
                isLoyal=false,
                alive=false
            }
        ],
        boys=[
            tom,
            jerry,
            jack
        ]
    }
}

還有關於這個Student類例項化的物件,呼叫toString()方法,可以可以這麼完美,你們不好奇麼?為什麼不是返回的一個Java記憶體地址,而是我們可以看的懂的一個類似json物件的字串格式呢?這裡面也是大有文章的,細心的小夥伴們,可以回頭看下我的三個javabean,這三個Java model都是重寫了toString()方法的,所以,你在呼叫最上層的toString()方法的時候,他會一次巢狀呼叫的。所以,才會這樣,這個好像我當時測試什麼的時候發現的,既然總結到這了,就多囉嗦兩句吧,看官要是不信的話,大可以把這個程式碼貼出來,去掉某個複寫的toString()方法,再自己測試一下,就可以看到,我所言非虛啦。

關於使用中的問題。

在使用json字串轉Java物件的時候,可能會拋異常,我這遇到的是因為,我的Dog類,沒有預設的建構函式,所以,就轉換失敗了,當添加了預設建構函式之後,就OK啦。看下圖的異常截圖。



可以看到,我這個預設的建構函式是剛剛新增的。

關於這個預設的建構函式,我們在實際開發的時候,還是一定要記的隨時都給寫上,不管自己用不用,都要加上,下面是我因為這個預設建構函式又出的bug。看連結:

好了,到此算是囉嗦完了。

等下,還是再囉嗦一下,

這個fastjson是在github上開源的,看連結: