关于Java JSON库的选择

JacksonFastjson(目前推荐用fastjson2)都是Java平台非常流行的JSON库,它们在性能方面不分伯仲,差距并不明显。如果是出于性能方面的考虑,任选其一皆可。

如下是测试相关参数,配置及代码:

  • Fastjson:2.0.60
  • Jackson:2.20.1

添加如下依赖:

<!-- fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.60</version>
</dependency>

<!-- jackson -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.20.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.16.1</version>
    <scope>compile</scope>
    <exclusions>
        <exclusion>
            <artifactId>jackson-annotations</artifactId>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
        <exclusion>
            <artifactId>jackson-core</artifactId>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
        <exclusion>
            <artifactId>jackson-databind</artifactId>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
</dependency>

用于测试的Java类:

/**
 * 用于序列化和反序列化测试的复杂对象
 */
public class ComplexJsonObject {
    private Map<String, String> map;
    private List<Integer> list;
    private String str;
    private Integer i;
    private Long l;
    private Double d;
    private Float f;
    private Short s;
    private Byte b;
    private Character c;
    private Boolean bool;
    
    public Map<String, String> getMap() {
        return map;
    }
    
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    
    public List<Integer> getList() {
        return list;
    }
    
    public void setList(List<Integer> list) {
        this.list = list;
    }
    
    public String getStr() {
        return str;
    }
    
    public void setStr(String str) {
        this.str = str;
    }
    
    public Integer getI() {
        return i;
    }
    
    public void setI(Integer i) {
        this.i = i;
    }
    
    public Long getL() {
        return l;
    }
    
    public void setL(Long l) {
        this.l = l;
    }
    
    public Double getD() {
        return d;
    }
    
    public void setD(Double d) {
        this.d = d;
    }
    
    public Float getF() {
        return f;
    }
    
    public void setF(Float f) {
        this.f = f;
    }
    
    public Short getS() {
        return s;
    }
    
    public void setS(Short s) {
        this.s = s;
    }
    
    public Byte getB() {
        return b;
    }
    
    public void setB(Byte b) {
        this.b = b;
    }
    
    public Character getC() {
        return c;
    }
    
    public void setC(Character c) {
        this.c = c;
    }
    
    public Boolean getBool() {
        return bool;
    }
    
    public void setBool(Boolean bool) {
        this.bool = bool;
    }
}

/**
 * 用于序列化和反序列化测试的简单对象
 */
public class SimpleJsonObject {
    private String str;
    private Integer i;
    private Long l;
    private Double d;
    private Float f;
    private Short s;
    private Byte b;
    private Character c;
    private Boolean bool;
    
    public String getStr() {
        return str;
    }
    
    public void setStr(String str) {
        this.str = str;
    }
    
    public Integer getI() {
        return i;
    }
    
    public void setI(Integer i) {
        this.i = i;
    }
    
    public Long getL() {
        return l;
    }
    
    public void setL(Long l) {
        this.l = l;
    }
    
    public Double getD() {
        return d;
    }
    
    public void setD(Double d) {
        this.d = d;
    }
    
    public Float getF() {
        return f;
    }
    
    public void setF(Float f) {
        this.f = f;
    }
    
    public Short getS() {
        return s;
    }
    
    public void setS(Short s) {
        this.s = s;
    }
    
    public Byte getB() {
        return b;
    }
    
    public void setB(Byte b) {
        this.b = b;
    }
    
    public Character getC() {
        return c;
    }
    
    public void setC(Character c) {
        this.c = c;
    }
    
    public Boolean getBool() {
        return bool;
    }
    
    public void setBool(Boolean bool) {
        this.bool = bool;
    }
}

/**
 * Fastjson工具
 */
public final class FastjsonUtil {
    
    /**
     * 将对象序列化为JSON字符串
     * @param obj
     * @return
     */
    public static String toJSON(Object obj) {
        return JSON.toJSONString(obj);
    }
    
    /**
     * 将JSON字符串反序列化为对象
     * @param json
     * @param clazz
     * @return
     * @param <T>
     */
    public static <T> T fromJSON(String json, Class<T> clazz) {
        return JSON.parseObject(json, clazz);
    }
}

/**
 * Jackson工具
 */
public final class JacksonUtil {
    private static final ObjectMapper mapper;
    
    static {
        mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.registerModule(new JavaTimeModule());
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }
    
    /**
     * 将对象序列化为JSON字符串
     * @param obj
     * @return
     */
    public static String toJSON(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将JSON字符串反序列化为对象
     * @param json
     * @param clazz
     * @return
     * @param <T>
     */
    public static <T> T fromJSON(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 格式化JSON字符串
     * @param json
     * @return
     */
    public static String formatJSON(String json) {
        try {
            Object obj = mapper.readValue(json, Object.class);
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

/**
 * JSON序列化和反序列化测试
 */
public class JsonUtilTest extends TestCase {
    private ComplexJsonObject complexJsonObject = new ComplexJsonObject();
    private SimpleJsonObject simpleJsonObject = new SimpleJsonObject();
    
    {
        init();
    }
    
    public void init () {
        Map<String, String> map = new HashMap<String, String>();
        for (int i = 0; i < 50000; i++) {
            map.put("key" + i, "value" + i);
        }
        
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 50000; i++) {
            list.add(i);
        }
        
        complexJsonObject.setMap(map);
        complexJsonObject.setList(list);
        complexJsonObject.setStr("This is complex json object string");
        complexJsonObject.setI(1);
        complexJsonObject.setL(100000000L);
        complexJsonObject.setD(1.0);
        complexJsonObject.setF(3.14f);
        complexJsonObject.setS((short) 10);
        complexJsonObject.setB(Byte.valueOf((byte) 1));
        complexJsonObject.setC(Character.valueOf('c'));
        complexJsonObject.setBool(true);
        
        simpleJsonObject.setStr("This is simple json object string");
        simpleJsonObject.setI(1);
        simpleJsonObject.setL(100000000L);
        simpleJsonObject.setD(1.0);
        simpleJsonObject.setF(3.14f);
        simpleJsonObject.setS((short) 10);
        simpleJsonObject.setB(Byte.valueOf((byte) 1));
        simpleJsonObject.setC(Character.valueOf('c'));
        simpleJsonObject.setBool(true);
    }
    
    /**
     * 测试FastjsonUtil工具
     */
    public void testFastjsonUtilWithComplexObject() {
        long start = System.currentTimeMillis();
        String json = FastjsonUtil.toJSON(complexJsonObject);
        long end = System.currentTimeMillis();
        System.out.println("testFastjsonUtilWithComplexObject serialization took " + (end - start) + " ms");
        
        //System.out.println(json);
        
        start = System.currentTimeMillis();
        FastjsonUtil.fromJSON(json, ComplexJsonObject.class);
        end = System.currentTimeMillis();
        System.out.println("testFastjsonUtilWithComplexObject deserialization took " + (end - start) + " ms");
    }
    
    /**
     * 测试FastjsonUtil工具
     */
    public void testFastjsonUtilWithSimpleObject() {
        long start = System.currentTimeMillis();
        String json = FastjsonUtil.toJSON(simpleJsonObject);
        long end = System.currentTimeMillis();
        System.out.println("testFastjsonUtilWithSimpleObject serialization took " + (end - start) + " ms");
        
        //System.out.println(json);
        
        start = System.currentTimeMillis();
        FastjsonUtil.fromJSON(json, SimpleJsonObject.class);
        end = System.currentTimeMillis();
        System.out.println("testFastjsonUtilWithSimpleObject deserialization took " + (end - start) + " ms");
    }
    
    /**
     * 测试JacksonUtil工具
     */
    public void testJacksonUtilWithComplexObject() {
        long start = System.currentTimeMillis();
        String json = JacksonUtil.toJSON(complexJsonObject);
        long end = System.currentTimeMillis();
        System.out.println("testJacksonUtilWithComplexObject serialization took " + (end - start) + " ms");
        
        //System.out.println(json);
        
        start = System.currentTimeMillis();
        JacksonUtil.fromJSON(json, ComplexJsonObject.class);
        end = System.currentTimeMillis();
        System.out.println("testJacksonUtilWithComplexObject deserialization took " + (end - start) + " ms");
    }
    
    /**
     * 测试JacksonUtil工具
     */
    public void testJacksonUtilWithSimpleObject() {
        long start = System.currentTimeMillis();
        String json = JacksonUtil.toJSON(simpleJsonObject);
        long end = System.currentTimeMillis();
        System.out.println("testJacksonUtilWithSimpleObject serialization took " + (end - start) + " ms");
        
        //System.out.println(json);
        
        start = System.currentTimeMillis();
        JacksonUtil.fromJSON(json, SimpleJsonObject.class);
        end = System.currentTimeMillis();
        System.out.println("testJacksonUtilWithSimpleObject deserialization took " + (end - start) + " ms");
    }
}

但是如果考虑流行度,文档全面性,兼容性,特性支持,BUG监测等方面,就需要慎重选择了。

比如:Spring全家桶默认使用的JSON库是Jackson,考虑到兼容性可能需要优先考虑使用它。如果在序列化和反序列化时还需要考虑某些特性支持,还需要专门测试验证后进行敲定。

【参考】
深度对比Jackson和Fastjson,最终我还是选择了
Spring Boot Jackson 和Fast JSON 用哪个好啊


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,在下面评论区告诉我^_^^_^