zoukankan      html  css  js  c++  java
  • json-lib(ezmorph)、gson、flexJson、fastjson、jackson对比,实现java转json,json转java

    json-lib(ezmorph)、gson、flexJson、fastjson、jackson对比,实现java转json,json转java

    本文中所讲的所有代码都在此:json-test

    目前关于java与json互转的工具包有很多 ,主流的主要有以下几个 :

    1. json-lib�0�2�0�2(依赖于�0�2ezmorph、commons-beanutils、commons-collections、groovy-all、oro、xom)
    2. gson
    3. flexjson
    4. fastjson
    5. jackson

    改天将各个工具包的特性(包括使用方便程度、序列化与反序列化的性能)列出来,便于大家使用,目前仅发现flexjson是最使用上简洁的、无依赖的工具包,能够轻松实现复杂的(树型多层结构,并且允许不同层对象中包含相同字段名)POJO转json。

    1、json-lib

            // java -> json
    		Classes sourceBean = TestCommon.getTestBean();
    
    		JsonConfig jc = new JsonConfig();
    		// 默认日期转换后的格式:"birthday":{"date":1,"day":3,"hours":0,"minutes":0,"month":0,"seconds":0,"time":-5364691200000,"timezoneOffset":-480,"year":-100}
    		// 这里添加格式自定义转换,解决默认日期格式不堪直视的问题。不加也可以,json-lib会把Date中所有字段输出出来,搞晕你。。。
    		jc.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
    		// 过滤掉为空的属性,json-lib默认会将为空的String初始化为"",为空的Number初始化为0,总之不会为null。对于POJO来说,这种做法没法区分包装类型是否为空,所以某种意义上来说
    		// ,json-lib多此一举了。
    		jc.setJsonPropertyFilter(new PropertyFilter() {
    
    			public boolean apply(Object source, String name, Object value) {
    				if (value == null) {
    					return true;
    				}
    				return false;
    			}
    		});
    		JSONObject jsonObject = JSONObject.fromObject(sourceBean, jc);
    		String jsonStr = jsonObject.toString();
    		System.out.println("java->json:" + jsonStr);
    
    		/** json -> java */
    		JSONUtils.getMorpherRegistry().registerMorpher(
    				new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" }));
    
    		jc = new JsonConfig();
    		jc.setRootClass(Classes.class); // 指定需要转换到的根类的类型。
    		// 问题来了,那么内部集合对应的类型哪里指定呢?通过测试发现,如果不指定会出现只有父类(Classes)会转换成原始的Bean,而其集合(students)属性会被自动转换成MorphDynaBean,这时候如果迭代这个List中对象,会抛出异常:java.lang.ClassCastException:
    		// net.sf.ezmorph.bean.MorphDynaBean cannot be cast to  com.zt.test.Student
    		// 关于这个问题,官方并没有明确指明,但通过查看源码发现有一个方法能解决这个问题:JSONObject.setClassMap
    		// ,该方法的官方声明【Sets the current attribute/Class Map ;classMap  : a Map of classes, every key identifies a property or a regexp 】
    		// 通过查看源码发现这就是我们想要的,通过它可以指定内部集合中包含的复合对象的类型,如果该内部类型中还包含了其它集合,处理 方法一样,统统加如到classMap中去,如下:
    
    		Map<String, Class> classMap = new HashMap<String, Class>();
    		classMap.put("students", Student.class); //指定Classes的students字段的内部类型
    		jc.setClassMap(classMap);
    
    		JSONObject targetJo = JSONObject.fromObject(jsonStr, jc);
    		Classes targetBean = (Classes) JSONObject.toBean(targetJo, jc);
    
    		System.out.println("json->java:" + BeanUtils.describe(targetBean));
    		assertEquals(targetBean.getStudents().get(0).getName(), "张扇风");
    

    2、gson

            package com.zt.test;
    
    import junit.framework.TestCase;
    
    import com.google.gson.Gson;
    
    public class GsonTest extends TestCase {
    
    	public void testGson() throws Exception {
    		Classes sourceBean = TestCommon.getTestBean();
    		Gson gson = new Gson();
    		// java -> json
    		String json = gson.toJson(sourceBean);
    //		System.out.println(json);
    
    		// json -> java
    		Classes targetBean = gson.fromJson(json, Classes.class);
    //		System.out.println(BeanUtils.describe(targetBean));
    		assertEquals(targetBean.getStudents().get(0).getName(), "张扇风");
    		assertEquals(targetBean.getStudents().get(0).getBirthday(), TestCommon.DATEFORMAT.parse("1800-01-01 01:00:00"));
    	}
    
    	public void testLoad() throws Exception {
    		for (int i = 0; i < 100000; i++) {
    			testGson();
    		}
    	}
    
    }
    
    

    3、flex-json

    // java -> json
    		Classes sourceBean = TestCommon.getTestBean();
    		JSONSerializer serializer = new JSONSerializer();
    
    		String jsonStr = serializer.deepSerialize(sourceBean);
    		//序列化的时候带着class字段,反序列化的时候就不需要指定目标class了。
    		System.out.println("java -> json:" + jsonStr);
    
    		// json -> java
    		JSONDeserializer deserializer = new JSONDeserializer();
    		Classes targetBean = (Classes) deserializer.deserialize(jsonStr);
    		System.out.println("json -> java:" + BeanUtils.describe(targetBean) );
    		assertEquals(targetBean.getStudents().get(0).getName(), "张扇风");
    

    4、fastjson

            package com.zt.test;
    
    import junit.framework.TestCase;
    
    import com.alibaba.fastjson.JSON;
    
    public class FastJsonTest extends TestCase{
    	public void testFastJson() throws Exception {
    		Classes sourceBean = TestCommon.getTestBean();
    		// java -> json
    		String json = JSON.toJSONString(sourceBean);
    
    //		System.out.println(json);
    
    		// json -> java
    		Classes targetBean = JSON.parseObject(json, Classes.class);
    
    //		System.out.println(BeanUtils.describe(targetBean));
    		assertEquals(targetBean.getStudents().get(0).getName(), "张扇风");
    		assertEquals(targetBean.getStudents().get(0).getBirthday(), TestCommon.DATEFORMAT.parse("1800-01-01 01:00:00"));
    	}
    
    	public void testLoad() throws Exception {
    		for (int i = 0; i < 100000; i++) {
    			testFastJson();
    		}
    	}
    
    }
    
    

    5、Jackson

            package com.zt.test;
    
    import junit.framework.TestCase;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public class JacksonTest extends TestCase{
    	public void testJackson() throws Exception {
    		Classes sourceBean = TestCommon.getTestBean();
    		// java -> json
    		ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
    
    		String json = mapper.writeValueAsString(sourceBean);
    
    //		System.out.println(json);
    
    		// json -> java
    		Classes targetBean = mapper.readValue(json, Classes.class);
    
    //		System.out.println(BeanUtils.describe(targetBean));
    		assertEquals(targetBean.getStudents().get(0).getName(), "张扇风");
    		assertEquals(targetBean.getStudents().get(0).getBirthday(), TestCommon.DATEFORMAT.parse("1800-01-01 01:00:00"));
    	}
    
    	public void testLoad() throws Exception {
    		for (int i = 0; i < 100000; i++) {
    			testJackson();
    		}
    	}
    
    }
    
    

    对比结果:

      依赖jar个数 上手容易度 功能、特性 性能  
    json-lib�0�2 5 java <-> json、xml<->json;
    自定义格式;
    属性过滤;
    25s  
    gson 1 java <-> json (待补充) 15s  
    flexjson 1 java <-> json(待补充) 12s  
    fastjson 1 java <-> json(待补充) 3s  
    jackson 1 java <-> json(待补充) 87s  
       
    性能测试:单个用例测试10W次java-json互转,测试多次取均速,测试非严格,只看相对性能就好,如果对测试结果有疑问的可以自己下载源码测试
  • 相关阅读:
    .Net 并发写入文件的多种方式
    变量命名神器——CODELF
    Python打包发布
    python工具——NumPy
    python工具——Pandas
    没事早点睡
    python工具——pixellib
    Tensorflow在Windows下使用踩坑
    python工具——Tesseract
    python工具——wordcloud
  • 原文地址:https://www.cnblogs.com/daichangya/p/12958437.html
Copyright © 2011-2022 走看看