转载

jackson,fastjson,Gson比较分析

1 快并不是唯一需要考虑的因素等,相对于数据库IO,json解析时间可以忽略不计

2 fastjson针对特定需求做了很多优化,导致校验不严格,比如数组[],夏令时,末尾不带,等都能转成对象

3 jackson功能更强大,可配置化程度更高(fastjson)

比如序列化guava类型,序列化java8中的时间日期等,常见配置如下

//序列化BigDecimal时之间输出原始数字还是科学计数, 默认false, 即是否以toPlainString()科学计数方式来输出
    objectMapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
    //允许将JSON空字符串强制转换为null对象值
    objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

    //允许单个数值当做数组处理
    objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

    //禁止重复键, 抛出异常
    objectMapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
    //禁止使用int代表Enum的order()來反序列化Enum, 抛出异常
    objectMapper.enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS);
    //有属性不能映射的时候不报错
    objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    //使用null表示集合类型字段是时不抛异常
    objectMapper.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
    //对象为空时不抛异常
    objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

    //允许在JSON中使用c/c++风格注释
    objectMapper.enable(JsonParser.Feature.ALLOW_COMMENTS);
    //强制转义非ascii字符
    objectMapper.disable(JsonGenerator.Feature.ESCAPE_NON_ASCII);
    //允许未知字段
    objectMapper.enable(JsonGenerator.Feature.IGNORE_UNKNOWN);
    //在JSON中允许未引用的字段名
    objectMapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
    //时间格式
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    //识别单引号
    objectMapper.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
    //识别特殊字符
    objectMapper.enable(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS);
    //识别Java8时间
    objectMapper.registerModule(new ParameterNamesModule());
    objectMapper.registerModule(new Jdk8Module());
    objectMapper.registerModule(new JavaTimeModule());
    //识别Guava包的类
    objectMapper.registerModule(new GuavaModule());

设置不同的name

// without annotation, we'd get "theName", but we want "name":
   @JsonProperty("name")
   public String getTheName() { return _name; }

忽略属性

// means that if we see "foo" or "bar" in JSON, they will be quietly skipped
// regardless of whether POJO has such properties
@JsonIgnoreProperties({ "foo", "bar" })
public class MyBean
{
   // will not be written as JSON; nor assigned from JSON:
   @JsonIgnore
   public String internal;

4 fastjson 某些实现方式存在争议,代码质量差,参考: https://pic3.zhimg.com/80/v2-...

fastjson在jdk1.7以下可能存在内存泄露,因为使用的substring,而jdk1.6substring存在内存泄露的keneng

参考: https://www.programcreek.com/...

//JDK 6
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
public String substring(int beginIndex, int endIndex) {
//check boundary
return new String(offset + beginIndex, endIndex - beginIndex, value); 
}

//JDK 7
public String(char value[], int offset, int count) {
    //check boundary
    this.value = Arrays.copyOfRange(value, offset, offset + count);
}
 
public String substring(int beginIndex, int endIndex) {
    //check boundary
    int subLen = endIndex - beginIndex;
    return new String(value, beginIndex, subLen);
}

5 Gson能处理json的三层嵌套

Gson能自动处理json的三层嵌套,比如,但jackson和fastjson都处理起来都非常麻烦(但是其实json并不推荐多层嵌套)

class C {
  B b;
}

class B{
 List<A> a
}

Class A{

}

jackson处理两层嵌套的方法:重写反序列化方法

public class Order {

    public String name;
    public List<Item> items;
}

class ItemsJsonDeserializer extends JsonDeserializer<List<Item>> {

    @Override
    public List<Item> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        InnerItems innerItems = jp.readValueAs(InnerItems.class);

        return innerItems.elements;
    }

    private static class InnerItems {
        public List<Item> elements;
    }
}

public class Order {
  public String name;
  @JsonDeserialize(using = ItemsJsonDeserializer.class)
  public List<Item> items;
}

6 jackson有更广泛的社区基础

原文  https://segmentfault.com/a/1190000020504347
正文到此结束
Loading...