写在前面

关于 java 对象的序列化与反序列化的问题,最近 阿里的fastJson在网上嘘声一片,很多遗留的Bug、issue都未解决等等…

其实也不要太警惕,java 的基本开发中,web开发、大数据开发,我目前接触、了解的也就这两个主流开发方向,关于对象的构造不是很复杂的话,阿里的FastJson就可以很方便的准确序列化,但是,目前中国,也存在一些真正的大牛、团队(类似阿里。腾讯,网易、百度等等大厂)在高级的框架设计中,会有频繁的序列化与反序列化的对象操作,这样可能对序列化要有更加准确的解析,类似 Spring ,Mybatis,apache 等等,他们都是基于 Jackson(fasterxml )封装的对象序列化实现方案…

一、简单比较

这里比较下,FastJson、Gson、fasterxml jackson的相关基础

  • FastJson

  • Gson

  • jackson


基本性能测试、有兴趣的可以去自己测试,序列化/反序列化最重要的准确解析数据。速度不是最重要的

二 、fastJson

2.1、示例一

    /** * {"id":123,"name":"一级部门"} * @throws Exception */
    public void test_0() throws Exception {
   
        Department dep = new Department();
        dep.setId(123);
        dep.setName("一级部门");
        dep.setParent(dep);        

        String text = JSON.toJSONString(dep);
        System.out.println(text);
        
        JSON.parseObject(text, Department.class);
    }

    public static class Department {
   

        private int                  id;
        private String               name;
        private Department parent;
        private transient List<Department> children = new ArrayList<Department>();

        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; }
        @JSONField(serialize=false)
        public Department getParent() {
    return parent; }
        public void setParent(Department parent) {
    this.parent = parent; }
        public List<Department> getChildren() {
    return children; }
        public void setChildren(List<Department> children) {
    this.children = children; }
    }

2.2、示例二

    /** * {"name":"Jobs","salary":8000,"age":50} * @throws Exception */
    public void test_0() throws Exception {
   
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", "Jobs");
        jsonObject.put("age", 50);
        jsonObject.put("salary", new BigDecimal(8000));

        String text = jsonObject.toJSONString();
        System.out.println(text);
    }

2.3、示例三

    /** * {"id":0,"name":"admin","users":[{"id":2,"name":"guest"},{"id":3,"name":"root"}]} * @throws Exception */
    public void test_encode() throws Exception {
   
        Group group = new Group();
        group.setId(0L);
        group.setName("admin");

        User guestUser = new User();
        guestUser.setId(2L);
        guestUser.setName("guest");

        User rootUser = new User();
        rootUser.setId(3L);
        rootUser.setName("root");

        group.getUsers().add(guestUser);
        group.getUsers().add(rootUser);

        String jsonString = JSON.toJSONString(group);

        System.out.println(jsonString);
        
        JSON.parseObject(jsonString, Group.class);
    }

2.4、示例四,name ,value 过滤

public void test_secure() throws Exception {
   

        ValueFilter filter = new ValueFilter() {
   

            public Object process(Object source, String name, Object value) {
   
                if (name.equals("name")) {
   
                    return "WSJ";
                }
                return value;
            }
        };

        NameFilter nameFilter = new NameFilter() {
   
            public String process(Object source, String name, Object value) {
   
                if (name.equals("id")) {
   
                    return "ID";
                }
                return name;
            }
        };

        String text = "{\"id\":123,\"name\":\"WJH\"}";

        Object object = JSON.parse(text);

        SerializeWriter out = new SerializeWriter();
        JSONSerializer serializer = new JSONSerializer(out);
        serializer.getValueFilters().add(filter);
        serializer.getNameFilters().add(nameFilter);

        serializer.write(object);

        String outText = out.toString();
        System.out.println(outText);
    }

2.5、demo5, @JSONField 使用

    public static class User {
   

        private int    id;
        private String name;

        @JSONField(name = "uid")
        public int getId() {
    return id; }

        @JSONField(name = "uid")
        public void setId(int id) {
    this.id = id; }

        public String getName() {
    return name; }

        public void setName(String name) {
    this.name = name; }
    }

    /** * {"name":"毛头","uid":123} * @throws Exception */
    public void test_0() throws Exception {
   
        User user = new User();
        user.setId(123);
        user.setName("毛头");

        String text = JSON.toJSONString(user);
        Assert.assertEquals("{\"name\":\"毛头\",\"uid\":123}", text);
        System.out.println(text);
    }

2.6、demo 6

/** * {"name":"张三","id":123} * {name=张三, id=123} */
public class MapDemo extends TestCase {
   
    public void test_0 () throws Exception {
   
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", 123);
        map.put("name", "张三");
        
        String text = JSON.toJSONString(map);
        System.out.println(text);
        System.out.println(map.toString());
    }
}

2.7、DefaultJSONParser

    public void test_reuse() throws Exception {
   
        Model model = new Model();

        {
   
            DefaultJSONParser parser = new DefaultJSONParser("{\"id\":123,\"name\":\"wangsai-silence\"}");
            parser.parseObject(model);
            parser.close(); // 调用close能重用buf,提升性能

            assertEquals(123, model.id);
            assertEquals("wangsai-silence", model.name);
        }

        {
   
            DefaultJSONParser parser = new DefaultJSONParser("{\"id\":234,\"name\":\"wenshao\"}");
            parser.parseObject(model);
            parser.close(); // 调用close能重用buf,提升性能

            assertEquals(234, model.id);
            assertEquals("wenshao", model.name);
        }
    }

    public static class Model {
   
        public int id;
        public String name;
    }

2.8、从文件中解析

    public void test_for_maiksagill() throws Exception {
   
        String resource = "json/maiksagill.json";
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
        String text = IOUtils.toString(is);

        System.out.println(text);
        JSON.parseObject(text, WareHouseInfo[].class);
    }     

2.9、Null 处理

public void test_boolean() throws Exception {
   
        Model model = new Model();
// String json = JSON.toJSONString(model, SerializerFeature.IgnoreNonFieldGetter); //{}
        String json = JSON.toJSONString(model,SerializerFeature.WriteNullStringAsEmpty); // {"available":true,"name":""}
// String json = JSON.toJSONString(model,SerializerFeature.WriteMapNullValue); // {"age":null,"available":true,"name":null}
        System.out.println(json);
    }

    public static class Model {
   
        private String name;
        private Long age;

        public String getName() {
   
            return name;
        }

        public void setName(String name) {
   
            this.name = name;
        }

        public Long getAge() {
   
            return age;
        }

        public void setAge(Long age) {
   
            this.age = age;
        }

        public boolean isAvailable() {
   
            return true;
        }
    }

简单列出这么多,其实 FastJson还是很强大的,比Gson ,Jackson 丰富很多序列化的实现

三、Gson

这里可参考这里,链接

四、Jackson

Jackson是框架设计中首选的,是可以肯定的