Java解析json(三):fastjson

介绍

fastjson是一个Java语言编写的JSON处理器。
- 遵循 http://json.org 标准,为其官方网站收录的参考实现之一。
- 功能比较强大,支持JDK的各种类型,包括基本的JavaBean、Collection、Map、Date、Enum、泛型。
要求: 序列化的类符合Java bean规范
Java解析json(三):fastjson_第1张图片

主要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 parseObject(String text, Class clazz); // 把JSON文本parse为JavaBean 
public static final JSONArray parseArray(String text); // 把JSON文本parse成JSONArray 
public static final  List parseArray(String text, Class 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, List, List >

 (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//多次测试,无序
        {  
           JSONObject jsonObject = JSONObject.parseObject(jsonObjectStr) ;  
           for(java.util.Map.Entry 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; kout.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 transfer2AdminList =  (List) JSON.parseObject(arrJsonStr, new TypeReference>(){});
    List transfer2AdminList =  (List) 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 list;
    public Seller(){} //必须有
    public Seller(int id, String name, List 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 getList() {
        return list;
    }
    public void setList(List 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 list = new ArrayList();
    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 list = new ArrayList<>();
    list.add(admin1);
    list.add(admin2);
    String listJsonStr = JSON.toJSONString(list);
    System.out.println("list2json result:"+listJsonStr);

    //JSON array -> List 
    List 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 map = new HashMap();
        map.put("admin1", admin1);
        map.put("admin2", admin2);
        String mapJsonStr = JSON.toJSONString(map);
        System.out.println("map2json result:"+mapJsonStr);

        //JSON -> Map 
        Map mapFromJson  = (Map) 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 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 list = new ArrayList();
    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 getList() {
        return list;
    }
    public void setList(List 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 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 toBean(String text, Class clazz) {
        return JSON.parseObject(text, clazz);
    }

    // 转换为数组
    public static  Object[] toArray(String text) {
        return toArray(text, null);
    }

    // 转换为数组
    public static  Object[] toArray(String text, Class clazz) {
        return JSON.parseArray(text, clazz).toArray();
    }

    // 转换为List
    public static  List toList(String text, Class clazz) {
        return JSON.parseArray(text, clazz);
    }

    /**
     * 将javabean转化为序列化的json字符串
     * @param keyvalue
     * @return
     */
    public static  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;
    }

}

安卓版本

fastjson有专门的for Android版本,去掉不常用的功能。jar占的字节数更小。Git branch地址是:https://github.com/alibaba/fastjson/tree/android 。

缺点

https://www.zhihu.com/question/44199956

参考

http://www.tuicool.com/articles/zUbQfa
http://blog.csdn.net/swust_chenpeng/article/details/19617561?locationNum=15&fps=1
alibaba fastjson(json序列化器)序列化部分源码解析-1-总体分析:
http://www.iflym.com/index.php/code/alibaba-fastjson-json-serializer-chapter-source-analyse-one-global-analyse.html
http://www.cnblogs.com/dirgo/p/5178629.html

你可能感兴趣的:(javaee)