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互转,测试多次取均速,测试非严格,只看相对性能就好,如果对测试结果有疑问的可以自己下载源码测试
  • 相关阅读:
    软件测试人员的年终绩效考核怎么应对
    收藏
    顶踩组件 前后两版
    订阅组件
    hdu 1963 Investment 完全背包
    hdu 4939 Stupid Tower Defense 动态规划
    hdu 4405 Aeroplane chess 动态规划
    cf 414B Mashmokh and ACM 动态规划
    BUPT 202 Chocolate Machine 动态规划
    hdu 3853 LOOPS 动态规划
  • 原文地址:https://www.cnblogs.com/daichangya/p/12958437.html
Copyright © 2011-2022 走看看