1. 程式人生 > >Java解析json(三):fastjson

Java解析json(三):fastjson

介紹

fastjson是一個Java語言編寫的JSON處理器。
- 遵循 http://json.org 標準,為其官方網站收錄的參考實現之一。
- 功能比較強大,支援JDK的各種型別,包括基本的JavaBean、Collection、Map、Date、Enum、泛型。
要求: 序列化的類符合Java bean規範
這裡寫圖片描述

主要API

Fastjson API入口類是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON類上的靜態方法直接完成。

反序列化

public static final Object parse(String text); // 把JSON字串轉化為JSONObject或者JSONArray 
public static final JSONObject parseObject(String text); // 把JSON字串轉化為JSONObject public static final <T> T parseObject(String text, Class<T> clazz); // 把JSON文字parse為JavaBean public static final JSONArray parseArray(String text); // 把JSON文字parse成JSONArray public static final <T> List<T> parseArray
(String text, Class<T> clazz); //把JSON字串轉化為JavaBean集合

序列化

public static final String toJSONString(Object object); // 將JavaBean序列化為JSON文字 
public static final String toJSONString(Object object, boolean prettyFormat); // 將JavaBean序列化為帶格式的JSON字串
public static final Object toJSON(Object javaObject); //將JavaBean轉換為JSONObject或者JSONArray。

測試案例

環境

  • jdk1.7+
  • 第三方jar包:fastjson-1.2.23.jar

常用型別

JavaBean, List<JavaBean>, List<String>, List<Map< String,Object> >

 (1) JavaBean
      Bean bean = JSON.parseObject(jsonString, bean.class);
 (2)List<JavaBean>
          List<bean> list =JSON.parseArray(jsonString, bean.class);
 (3)List<String>
          List<String> listString = JSON.parseArray(jsonString, String.class);
 (4)List<Map<String,Object>>
      List<Map<String, Object>> listMap = JSON.parseObject(jsonString, new TypeReference<List<Map<String,Object>>>(){});

JsonObject無序 JsonArray有序

@Test
public void Str2JsonObject(){
        String jsonObjectStr = "{'zhangxy':'張學友','liudh':'劉德華','lim':'黎明','guofc':'郭富城'}" ;  
        //做5次測試  
        for(int i=0,j=5;i<j;i++)  //多次測試,無序
        {  
           JSONObject jsonObject = JSONObject.parseObject(jsonObjectStr) ;  
           for(java.util.Map.Entry<String,Object> entry:jsonObject.entrySet()){  
               System.out.print(entry.getKey()+"-"+entry.getValue()+"\t");  
           }  
           System.out.println();//用來換行  
        } 
}

結果(無序):

zhangxy-張學友 guofc-郭富城   lim-黎明  liudh-劉德華   
zhangxy-張學友 guofc-郭富城   lim-黎明  liudh-劉德華   
zhangxy-張學友 guofc-郭富城   lim-黎明  liudh-劉德華   
zhangxy-張學友 guofc-郭富城   lim-黎明  liudh-劉德華   
zhangxy-張學友 guofc-郭富城   lim-黎明  liudh-劉德華   
@Test
public void Str2JsonArray(){
        String jsonArrayStr = "[{'zhangxy':'張學友'}, {'liudh':'劉德華'},{'lim':'黎明'},{'guofc':'郭富城'}]" ; 
        //做5次測試  
        for(int j=0;j<5;j++)  //多次測試,有序
        {  
           JSONArray jsonArray = JSONArray.parseArray(jsonArrayStr) ; 
           for (int k=0; k<jsonArray.size();k++){
               System.out.print(jsonArray.get(k) + "\t");
           }
           System.out.println();//用來換行  
        }  
}

結果(有序):

{"zhangxy":"張學友"} {"liudh":"劉德華"}  {"lim":"黎明"} {"guofc":"郭富城"} 
{"zhangxy":"張學友"} {"liudh":"劉德華"}  {"lim":"黎明"} {"guofc":"郭富城"} 
{"zhangxy":"張學友"} {"liudh":"劉德華"}  {"lim":"黎明"} {"guofc":"郭富城"} 
{"zhangxy":"張學友"} {"liudh":"劉德華"}  {"lim":"黎明"} {"guofc":"郭富城"} 
{"zhangxy":"張學友"} {"liudh":"劉德華"}  {"lim":"黎明"} {"guofc":"郭富城"} 

Bean和json相互轉換

簡單物件與json互相轉換

admin.java

class Admin{
    private int id;
    private String name;
    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;
    }
}

測試類

/**
 * 物件陣列轉json
 */
@Test
public void JsonStr2Bean(){
    Admin admin1 = new Admin();
    admin1.setId(1);
    admin1.setName("nowu");
    Admin admin2 = new Admin();
    admin2.setId(2);
    admin2.setName("seeme");
    Admin[] arrStr = {admin1,admin2};
    String arrJsonStr =  JSON.toJSONString(arrStr); //[{"id":1,"name":"admin1"},{"id":2,"name":"admin2"}]
//      List<Admin> transfer2AdminList =  (List<Admin>) JSON.parseObject(arrJsonStr, new TypeReference<List<Admin>>(){});
    List<Admin> transfer2AdminList =  (List<Admin>) JSON.parseArray(arrJsonStr, Admin.class);
    for (Admin admin: transfer2AdminList) {
        System.out.println(admin.getId()+":"+admin.getName());
    }
}

輸出結果:

1:nowu
2:seeme

複雜物件與json互相轉換

Bean中必須符合javaBean規範,如必須有無參建構函式,getter/setter書寫規範等。
Computer.java

import java.util.Date;
public class Computer {
    private Integer id;
    private Date produceTime;
    private String encodeNo;
    public Computer(){} //必須有
    public Computer(Integer id, Date produceTime, String encodeNo) {
        super();
        this.id = id;
        this.produceTime = produceTime;
        this.encodeNo = encodeNo;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Date getProduceTime() {
        return produceTime;
    }
    public void setProduceTime(Date produceTime) {
        this.produceTime = produceTime;
    }
    public String getEncodeNo() {
        return encodeNo;
    }
    public void setEncodeNo(String encodeNo) {
        this.encodeNo = encodeNo;
    }   
}

Seller.java

import java.util.List;
class Seller{
    private int id;
    private String name;
    private List<Computer> list;
    public Seller(){} //必須有
    public Seller(int id, String name, List<Computer> list) {
        super();
        this.id = id;
        this.name = name;
        this.list = list;
    }
    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 List<Computer> getList() {
        return list;
    }
    public void setList(List<Computer> list) {
        this.list = list;
    }
}

測試程式碼:

@Test
public void JsonStr2ComplexBean(){
    Computer c1 = new Computer(1,new Date(), "No.1");
    Computer c2 = new Computer(1,new Date(), "No.2");
    Computer c3 = new Computer(1,new Date(), "No.3");
    List<Computer> list = new ArrayList<Computer>();
    list.add(c1);
    list.add(c2);
    list.add(c3);
    Seller  seller = new Seller(1, "seller1", list);
    String sellerJsonStr = JSONObject.toJSONString(seller);
    System.out.println(sellerJsonStr);
    //{
    //  "id":1,
    //  "list":[{"encodeNo":"No.1","id":1,"produceTime":1487414094918},
    //          {"encodeNo":"No.2","id":1,"produceTime":1487414094918},
    //          {"encodeNo":"No.3","id":1,"produceTime":1487414094918}],
    //   "name":"seller1"
    //}
    Seller transfer2Seller = JSON.parseObject(sellerJsonStr, Seller.class);
    System.out.println(transfer2Seller.getId());
    for (Computer computer: transfer2Seller.getList()) {
        System.out.println(computer.getId()+" : "+computer.getEncodeNo());
    }
}

輸出結果:

1
1 : No.1
1 : No.2
1 : No.3

List和json相互轉換

/**
 * json轉list
 */
@Test
public void JsonStr2List(){
    //List -> JSON array
    Admin admin1 = new Admin();
    admin1.setId(1);
    admin1.setName("admin1");
    Admin admin2 = new Admin();
    admin2.setId(2);
    admin2.setName("admin2");
    List<Admin> list = new ArrayList<>();
    list.add(admin1);
    list.add(admin2);
    String listJsonStr = JSON.toJSONString(list);
    System.out.println("list2json result:"+listJsonStr);

    //JSON array -> List 
    List<Admin> list2 = JSON.parseArray(listJsonStr, Admin.class);
    for (Admin admin: list2) {
        System.out.println("id:"+admin.getId() +" name:"+admin.getName());
    }
}
執行結果:
list2json result: [{"id":1,"name":"admin1"},{"id":2,"name":"admin2"}]
id:1 name:admin1
id:2 name:admin2

Array和json相互轉換

普通陣列與json的互相轉換:

/**
 * array轉json
 */
@Test
public void Array2Json(){
    String[] arrStr = {"a","b","c","d"};
    String arrJsonStr =  JSON.toJSONString(arrStr);
    System.out.println("arr2str result:"+arrJsonStr);
    JSONArray jsonArray = JSON.parseArray(arrJsonStr);
    for (Object object : jsonArray) {
        System.out.println("iterator from JsonArray: "+object);
    }
    System.out.println("JsonArray:"+jsonArray);

}
執行結果:
arr2str result:["a","b","c","d"]
iterator from JsonArray: a
iterator from JsonArray: b
iterator from JsonArray: c
iterator from JsonArray: d
JsonArray:["a","b","c","d"]

物件陣列與json的互相轉換:

    /**
     * 物件陣列轉json
     */
    @Test
    public void ObjectArray2Json(){
        Admin admin1 = new Admin();
        admin1.setId(1);
        admin1.setName("admin1");
        Admin admin2 = new Admin();
        admin2.setId(2);
        admin2.setName("admin2");
        Admin[] arrStr = {admin1,admin2};
        String arrJsonStr =  JSON.toJSONString(arrStr,true);
        System.out.println("objectarr2str result:"+arrJsonStr);
        JSONArray jsonArray = JSON.parseArray(arrJsonStr);
        for (Object object : jsonArray) {
            System.out.println("iterator from JsonArray: "+object);
        }
        System.out.println("JsonArray:"+jsonArray);
    }

Map和json相互轉換

    /**
     * json轉map
     */
    @Test
    public void JsonStr2Map(){
        //Map -> JSON 
        Admin admin1 = new Admin();
        admin1.setId(1);
        admin1.setName("admin1");
        Admin admin2 = new Admin();
        admin2.setId(2);
        admin2.setName("admin2");
        Map<String, Admin> map = new HashMap<String, Admin>();
        map.put("admin1", admin1);
        map.put("admin2", admin2);
        String mapJsonStr = JSON.toJSONString(map);
        System.out.println("map2json result:"+mapJsonStr);

        //JSON -> Map 
        Map<String, Admin> mapFromJson  = (Map<String, Admin>) JSON.parse(mapJsonStr);
        for (String key: mapFromJson.keySet()) {
            System.out.println("key:"+ key+" value:"+mapFromJson.get(key));
        }

    }
執行結果:
map2json result:{"admin2":{"id":2,"name":"admin2"},"admin1":{"id":1,"name":"admin1"}}
key:admin2 value:{"id":2,"name":"admin2"}
key:admin1 value:{"id":1,"name":"admin1"}

重複引用

    /**
     * 重複引用
     */
    @Test
    public void  RepeatedRef() {
        List<Admin> list = new ArrayList<>();  
        Admin admin = new Admin(); 
        admin.setId(1);
        admin.setName("haha"); 
        list.add(admin);  
        list.add(admin);
        String s = JSON.toJSONString(list);
        System.out.println(s);
    }
執行結果:
[{"id":1,"name":"haha"},{"$ref":"$[0]"}]

迴圈引用

User.java

class User{
    private int id;
    private String name;
    private Group group;
    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 Group getGroup() {
        return group;
    }
    public void setGroup(Group group) {
        this.group = group;
    }

}

Group.java

import java.util.ArrayList;
import java.util.List;

class Group{
    private int id;
    private String name;
    private List<User> list = new ArrayList<User>();
    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 List<User> getList() {
        return list;
    }
    public void setList(List<User> list) {
        this.list = list;
    }
}
    /**
     * 迴圈引用
     */
    @Test
    public void RecyleRef(){
        Group group = new Group();  
        group.setId(1);  
        group.setName("group");  

        User user1 = new User();  
        user1.setId(2);  
        user1.setName("user1");  
        user1.setGroup(group);
        User user2 = new User();  
        user2.setId(3);  
        user2.setName("user2");  
        user2.setGroup(group);

        group.getList().add(user1);  
        group.getList().add(user2); 
        JSON.toJSONString(group, SerializerFeature.DisableCircularReferenceDetect); //java.lang.StackOverflowError
    }

迴圈引用,假如關閉引用檢查的話,執行會報StackOverflowError。不要關閉自定義的引用檢查
可以解決這個問題,但有時候想重複引用時並不想fastjson檢查我們的引用,所以這種辦法有時不靠譜,另一種為設定過濾欄位,自定義序列化欄位。

過濾和自定義序列化

SerializeFilter是通過程式設計擴充套件的方式定製序列化。fastjson支援6種SerializeFilter,用於不同場景的定製序列化。

  • PropertyPreFilter :根據PropertyName判斷是否序列化
  • PropertyFilter:根據PropertyName和PropertyValue來判斷是否序列化
  • NameFilter 修改Key,如果需要修改Key,process返回值則可
  • ValueFilter 修改Value
  • BeforeFilter :序列化時在最前面新增內容
  • AfterFilter :序列化時在最後面新增內容
@Test
    public void RecyleRef(){
        Group group = new Group();  
        group.setId(1);  
        group.setName("group");  

        User user1 = new User();  
        user1.setId(2);  
        user1.setName("user1");  
        user1.setGroup(group);
        User user2 = new User();  
        user2.setId(3);  
        user2.setName("user2");  
        user2.setGroup(group);

        group.getList().add(user1);  
        group.getList().add(user2); 
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter(User.class,"id","name");
        String result = JSON.toJSONString(group,filter);
        System.out.println(result);
    }
執行結果:
{"id":1,"list":[{"id":2,"name":"user1"},{"id":3,"name":"user2"}],"name":"group"}


    @Test
    public void Define1(){
        Group group = new Group();  
        group.setId(1);  
        group.setName("group");  
        User user1 = new User();  
        user1.setId(2);  
        user1.setName("user1");  
        user1.setGroup(group);
        User user2 = new User();  
        user2.setId(3);  
        user2.setName("user2");  
        user2.setGroup(group);
        group.getList().add(user1);  
        group.getList().add(user2); 
        //自定義序列化過濾器
        ValueFilter valueFilter = new ValueFilter() {
            @Override
            public Object process(Object o, String propertyName, Object propertyValue) {
                if(propertyName.equals("group")){
                   return new String("i am group");    //返回修改後的屬性值物件
                }

                return propertyValue;
            }
        };
        String result = JSON.toJSONString(group,valueFilter);
        System.out.println(result);
    }
執行結果:
{"id":1,"list":[{"group":"i am group","id":2,"name":"user1"},{"group":"i am group","id":3,"name":"user2"}],"name":"group"}

日期格式化

註解@JSONField

@JSONField (format=”yyyy-MM-dd HH:mm:ss”)
public Date date;

通過SerializeConfig

@Test
public void formatDateTest(){
China china = new China();  
china.setId(1);
    china.setName("中國"); 
    china.setCreateTime(new Date());
    List<Province> provinces = new ArrayList<>();  

    Province hei = new Province();  
    hei.setName("黑龍江");  
    City heiCity = new City();  
    heiCity.setCity(new String[] { "哈爾濱", "大慶" });  
    hei.setCitys(heiCity);  
    provinces.add(hei);  

    Province guang = new Province();  
    guang.setName("廣東");  
    City guangCity = new City();  
    guangCity.setCity(new String[] { "廣州", "深圳", "珠海" });  
    guang.setCitys(guangCity);  
    provinces.add(guang);  

    Province tai = new Province();  
    tai.setName("臺灣");  
    City taiCity = new City();  
    taiCity.setCity(new String[] { "臺北", "高雄 " });  
    tai.setCitys(taiCity);  
    provinces.add(tai);  

    china.setProvinces(provinces);  

    SerializeConfig serializeConfig = new SerializeConfig();  
    String dateFormat = "yyyy-MM-dd HH:mm:ss";  
    serializeConfig.put(Date.class, new SimpleDateFormatSerializer(dateFormat));


    String result=JSON.toJSONString(china,serializeConfig);
    System.out.println(result);
 }

SerializerFeature.WriteDateUseDateFormat

String result=JSON.toJSONString(china,SerializerFeature.WriteDateUseDateFormat);

JSON.toJSONStringWithDateFormat

   String result = JSON.toJSONStringWithDateFormat(china, "yyyy-MM-dd HH:mm:ss.SSS");

fastjson工具類

import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.JSONLibDataFormatSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * fastjson工具類
 */
public class FastJsonUtils {

    private static final SerializeConfig config;

    static {
        config = new SerializeConfig();
        config.put(java.util.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib相容的日期輸出格式
        config.put(java.sql.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib相容的日期輸出格式
    }

    private static final SerializerFeature[] features = {
            SerializerFeature.WriteMapNullValue, // 輸出空置欄位
            SerializerFeature.WriteNullListAsEmpty, // list欄位如果為null,輸出為[],而不是null
            SerializerFeature.WriteNullNumberAsZero, // 數值欄位如果為null,輸出為0,而不是null
            SerializerFeature.WriteNullBooleanAsFalse, // Boolean欄位如果為null,輸出為false,而不是null
            SerializerFeature.WriteNullStringAsEmpty, // 字元型別欄位如果為null,輸出為"",而不是null
    };


    public static String toJSONString(Object object) {
        return JSON.toJSONString(object, config, features);
    }

    public static String toJSONNoFeatures(Object object) {
        return JSON.toJSONString(object, config);
    }



    public static Object toBean(String text) {
        return JSON.parse(text);
    }

    public static <T> T toBean(String text, Class<T> clazz) {
        return JSON.parseObject(text, clazz);
    }

    // 轉換為陣列
    public static <T> Object[] toArray(String text) {
        return toArray(text, null);
    }

    // 轉換為陣列
    public static <T> Object[] toArray(String text, Class<T> clazz) {
        return JSON.parseArray(text, clazz).toArray();
    }

    // 轉換為List
    public static <T> List<T> toList(String text, Class<T> clazz) {
        return JSON.parseArray(text, clazz);
    }

    /**
     * 將javabean轉化為序列化的json字串
     * @param keyvalue
     * @return
     */
    public static <T> Object beanToJson(T t) {
        String textJson = JSON.toJSONString(t);
        Object objectJson  = JSON.parse(textJson);
        return objectJson;
    }

    /**
     * 將string轉化為序列化的json字串
     * @param keyvalue
     * @return
     */
    public static Object textToJson(String text) {
        Object objectJson  = JSON.parse(text);
        return objectJson;
    }

    /**
     * json字串轉化為map
     * @param s
     * @return
     */
    public static Map stringToCollect(String s) {
        Map m = JSONObject.parseObject(s);
        return m;
    }

    /**
     * 將map轉化為string
     * @param m
     * @return
     */
    public static String collectToString(Map m) {
        String s = JSONObject.toJSONString(m);
        return s;
    }

}

安卓版本

缺點

參考