fastJSON从0到1

分布式朝闻道

共 11257字,需浏览 23分钟

 · 2023-05-18

Fastjson是一个Java应用程序中操作JSON对象的Java类库,它可以将Java对象转换为JSON格式的字符串,并将JSON字符串转换为Java对象。Fastjson的速度非常快,是目前市面上最快的JSON库之一。

快速入门

1.添加maven依赖

      
      <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

2.将Java对象转换为JSON字符串

      
      import com.alibaba.fastjson.JSON;

public class User {
    private String name;
    private int age;

    // getter、setter方法
}
      
      public class Main {
    public static void main(String[] args) {
        User user = new User();
        user.setName("Tom");
        user.setAge(20);

        String jsonString = JSON.toJSONString(user);
        System.out.println(jsonString); // {"age":20,"name":"Tom"}
    }
}

3.将JSON字符串转换为Java对象

      
      import com.alibaba.fastjson.JSON;

public class User {
    private String name;
    private int age;

    // getter、setter方法
}

public class Main {
    public static void main(String[] args) {
        String jsonString = "{\"age\":20,\"name\":\"Tom\"}";

        User user = JSON.parseObject(jsonString, User.class);
        System.out.println(user.getName()); // Tom
        System.out.println(user.getAge()); // 20
    }
}
常用API

1.将Java对象转换为JSON字符串

      
      public static String toJSONString(Object object);
public static String toJSONString(Object object, SerializerFeature... features);

示例:

      
      User user = new User();
user.setName("Tom");
user.setAge(20);

String jsonString1 = JSON.toJSONString(user);
System.out.println(jsonString1); // {"age":20,"name":"Tom"}

String jsonString2 = JSON.toJSONString(user, SerializerFeature.WriteMapNullValue);
System.out.println(jsonString2); // {"name":"Tom","age":20,"school":null}

2.将JSON字符串转换为Java对象

      
      public static <T> T parseObject(String text, Class<T> clazz);
public static <T> T parseObject(String text, TypeReference<T> type);

示例:

      
      String jsonString = "{\"age\":20,\"name\":\"Tom\"}";

User user = JSON.parseObject(jsonString, User.class);
System.out.println(user.getName()); // Tom
System.out.println(user.getAge()); // 20

3.转换为JSONObject或JSONArray对象

      
      public static JSONObject parseObject(String text);
public static JSONArray parseArray(String text);

示例:

      
      String jsonString = "{\"name\":\"Tom\",\"age\":20}";

JSONObject jsonObject = JSON.parseObject(jsonString);
System.out.println(jsonObject.getString("name")); // Tom
System.out.println(jsonObject.getIntValue("age")); // 20

JSONArray jsonArray = JSON.parseArray("[\"Tom\",20]");
System.out.println(jsonArray.get(0)); // Tom
System.out.println(jsonArray.getIntValue(1)); // 20
序列化特征

Fastjson序列化时,可以设置一些特殊的序列化特征。

示例:

      
      import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class User {
    private String name;
    private int age;

    // getter、setter方法
}

public class Main {
    public static void main(String[] args) {
        User user = new User();
        user.setName("Tom");
        user.setAge(20);

        String jsonString = JSON.toJSONString(user, SerializerFeature.PrettyFormat, SerializerFeature.WriteDateUseDateFormat);
        System.out.println(jsonString);
        /**
         * {
         *     "age": 20,
         *     "name""Tom"
         * }
         */
    }
}

常用序列化特征:

序列化特征名称 功能
WriteMapNullValue 是否输出值为null的字段,默认为false
WriteNullListAsEmpty 是否输出空的List,默认为false
WriteNullStringAsEmpty 是否输出空的字符串,默认为false
WriteNullBooleanAsFalse 是否输出为null的布尔字段,默认为false
PrettyFormat 是否格式化输出,默认为false
BeanToArray 是否序列化Bean时输出class名称,默认为false
WriteDateUseDateFormat 是否使用DateFormat进行日期格式化输出,默认为false

到此我们了解了Fastjson的使用方法以及常用API和序列化特征。Fastjson是JSON解析库中的佼佼者,在实际项目中也有广泛的应用。Fastjson使用简单、兼容性好、效率高,值得开发者使用。

fastjson使用中有哪些注意点
  • 安全问题:Fastjson在高版本(1.2.24及之前)中存在反序列化漏洞,攻击者可以通过构造恶意JSON数据来执行任意代码。因此,建议使用最新版本的Fastjson库。

  • JSON数据格式问题:Fastjson对于不符合JSON数据格式的数据可能会出现解析错误。例如,对象或数组的括号不匹配,或者键或值不用双引号括起来等。建议在使用Fastjson时确保JSON数据符合规范。

  • Java对象中的属性问题:Fastjson在序列化Java对象时,会忽略值为null的属性,这个可以通过设置SerializerFeature.WriteMapNullValue来进行处理。而如果属性有getter方法但无setter方法,Fastjson在序列化时也无法将属性值传递给JSON,需要添加setter方法或使用注解 @JSONField(serialize = false) 来处理。另外,序列化时不能处理自引用或循环引用的对象,可以使用SerializerFeature.DisableCircularReferenceDetect来禁止处理循环引用。

  • 特殊字符问题:Fastjson在转换时会对特殊字符进行转义,例如双引号、单引号、换行符等。但需要注意的是,在某些特殊场景下,这些转义可能会导致问题,例如将JSON数据作为HTML的一部分输出,需要对特殊字符进行进一步处理。

  • 注解问题:Fastjson提供了一些注解用于定制序列化或反序列化的行为,如 @JSONField、@JSONType 等。需要了解这些注解及其使用方法,才能更好地使用Fastjson。

总的来说,使用Fastjson需要注意数据格式、Java对象属性、特殊字符、注解等问题,才能正确高效地进行JSON序列化和反序列化。

生产中如何优雅使用fastjson

在生产环境中,我们可以考虑以下几点来优雅地使用Fastjson:

  • 尽量选择最新版本的Fastjson,并及时更新:Fastjson在不断地进行优化和修复,我们应该选择最新版本的Fastjson,并及时更新以获得更好的性能和安全性。

  • 确认JSON数据格式正确:在使用Fastjson时,我们需要确认JSON数据格式正确,避免因格式不正确而导致解析出错。我们可以使用在线JSON格式校验工具或专业的JSON格式校验库来进行格式校验。

  • 使用合适的Fastjson配置:Fastjson提供了很多配置选项可以优化序列化和反序列化的性能,我们应该理解这些配置选项并选择合适的配置以获得更好的性能和安全性。

  • 对Java对象进行优化:Fastjson在序列化和反序列化Java对象时,会对对象的所有属性都进行处理。如果Java对象中存在一些不需要处理的属性,可以使用 @JSONField 注解或 SerializerFeature.IgnoreNonFieldGetter 等配置选项来忽略这些属性,从而提升性能。

  • 使用Fastjson扩展功能:Fastjson提供了很多扩展功能,如日期格式化、JSON对象/数组操作等,我们可以学习并使用这些功能,使代码更简洁和优雅。

  • 处理Fastjson安全问题:Fastjson在早期版本中存在反序列化漏洞,为了避免漏洞带来的安全问题,我们应该使用最新版的Fastjson,控制输入数据的来源和格式,对反序列化的结果进行安全性验证等。

我们可以通过选择最新版的Fastjson、确认JSON格式、配置选项、对象优化、扩展功能和安全处理等方面来优雅地使用Fastjson。

fastjson使用了哪些设计模式

在Fastjson中,有以下常见的设计模式:

  1. 工厂模式:Fastjson使用工厂模式来创造解析器(JSONReader、JSONWriter)和序列化器(JSONSerializer)。对于解析器,使用了JSONToken的工厂模式。

  2. 建造者模式:Fastjson使用建造者模式来创建JSON对象和JSONArray对象。

  3. 单例模式:在Fastjson中,一些重要的类(例如SerializerFeature)使用单例模式来确保整个应用程序中只有一个实例存在。

  4. 静态工具类模式:Fastjson中定义了一些静态工具类,如JSON、JSONObject等,这些工具类提供了一些方便的方法来操作JSON数据。

  5. 策略模式:Fastjson使用策略模式来完成序列化和反序列化。通过使用Serializer和Deserializer接口,Fastjson允许用户自定义序列化和反序列化逻辑。

  6. 观察者模式:Fastjson在解析JSON字符串时,通过触发事件来通知观察者的方式,在不同的解析阶段(例如开始、结束、键和值等)触发不同的事件通知观察者。

Fastjson使用了多种不同的设计模式,这些模式帮助Fastjson更好地实现了它的功能,同时也使得它的代码更加清晰易懂和易于维护。

核心API设计

当我们要进行Java对象与JSON的转换时,Fastjson提供了两个主要的API:toJSONString()方法和parseObject()方法。toJSONString()方法可以将Java对象序列化为JSON格式字符串;parseObject()方法可以将JSON格式字符串反序列化为Java对象。这两个API非常方便易用,具体实现细节如下:

toJSONString()方法的实现细节

toJSONString()方法是Fastjson序列化Java对象的核心方法。首先,Fastjson会通过反射机制来获取Java对象的所有属性和属性值,然后根据这些属性和属性值构建JSON格式的字符串,并返回。要注意的是,Fastjson对于不同数据类型的Java对象会进行不同的处理,例如对于Java的Date类型,Fastjson会自动将日期格式化为字符串返回。

      
      public static String toJSONString(Object object, boolean prettyFormat) {
      SerializeWriter out = new SerializeWriter((Writer)null, defaultBufferSize);
      try {
          JSONSerializer serializer = new JSONSerializer(out);
          if (prettyFormat) {
              serializer.config(SerializerFeature.PrettyFormat, true);
          }

          serializer.write(object);
          return out.toString();
      } finally {
          out.close();
      }
  }

parseObject()方法的实现细节

parseObject()方法是Fastjson反序列化JSON字符串的核心方法。首先,Fastjson会根据JSON格式字符串的语法规则,将JSON格式字符串解析为JSON对象,然后根据Java对象对应的数据结构,将JSON对象转换成Java对象,最后返回Java对象。需要注意的是,Fastjson支持对于泛型类型、复合对象等的反序列化操作。

      
      public static final <T> T parseObject(String json, TypeReference<T> type, Feature... features) {
      if (json == null) {
          return null;
      } else {
          Object object = JSON.parse(json, features);

          return cast(object, type);

除了以上的两个API,Fastjson还提供了很多其他方便易用的API,例如自定义序列化和反序列化器、JSON格式化输出、数组和集合的处理以及数据类型的转换等,在实际使用中可以根据需要进行选择,增加应用程序的性能和扩展性。

比如:

自定义序列化和反序列化器

Fastjson 提供了 SerializeFilter 和 ValueFilter 等接口,可以使用这些接口来自定义序列化和反序列化的方式。其中,SerializeFilter 用于在序列化时过滤部分字段,实现类似于 @JsonIgnore 和 @JsonProperty 的功能;ValueFilter 用于在序列化时修改字段的值,可以用来实现一些自定义转换逻辑。

JSON 格式化输出

Fastjson 提供了 SerializerFeature.PrettyFormat 配置项,可以输出带有缩进和换行符的美化 JSON 字符串,可以在调试时使用。

数组和集合的处理

Fastjson 支持将数组和集合类型的对象序列化为 JSON 字符串,并提供了一些方便的操作方法,比如 JSONArray.add() 和 JSONArray.get() 等,可以用来操作 JSONArray 对象;另外,Fastjson 还提供了 TypeReference接口,可以用来获取泛型类型的实际类型。

数据类型的转换

Fastjson 支持将 JSON 字符串自动转换成 Java 对象,需要满足对象中属性名和 JSON 中键名一致,并且 JSON 中键名与对象中属性名大小写敏感。同时,Fastjson 还支持将 Java 对象转换成 JSON 字符串、将基本类型的值转换成包装类型,以及将字符串类型的值转换成其他数据类型等。

Fastjson 提供了很多强大的 API,可以在实际开发中帮助我们实现更加灵活和可扩展的应用程序,并提高了应用程序的性能和可维护性。

fastJson不同版本的特性及bug修复情况

Fastjson 从 1.x 版本至今已经经历了很多年的发展,其各个版本都有不同的新增特性和重要的 bug 修复。下面就是 Fastjson 不同版本的特性和 bug 修复情况:

Fasjson 1.x 版本特性

Fastjson 1.x 版本是 Fastjson 最初发布的版本,其特性包括:

  • 支持将 JSON 字符串转换成 Java 对象;

  • 支持将 Java 对象序列化成 JSON 字符串;

  • 支持将 Java 对象序列化成 JSON 流;

  • 支持 JSON 与 JavaBean 的自动转换;

  • 可以使用 @JSONField 注解来映射属性名;

  • 支持自定义对象序列化方式;

  • 支持将 JSON 模板转换成 JavaBean。

Fastjson 1.x 版本 bug 修复

Fastjson 1.x 版本主要修复了以下重要的 bug:

  • 修复某些情况下会导致 JSON 解析错误的问题;

  • 修复在某些环境中会导致内存泄露的问题;

  • 解决在某些情况下无法正确地序列化 BigDecimal 类型的问题;

  • 修复某些情况下重复反序列化可能会导致属性丢失的问题;

  • 修复某些情况下 JSON 解析会出现错误的问题。

Fastjson 2.x 版本特性

Fastjson 2.x 版本是 Fastjson 的重要更新版本,其特性包括:

  • 支持自定义序列化和反序列化器;

  • 支持 JSON 格式化输出;

  • 支持将数组和集合类型的对象序列化为 JSON 字符串;

  • 支持将 Java 对象转换成 JSON 字符串;

  • 支持通过 getter 和 setter 方法来访问对象的属性值;

  • 支持将 Java 对象转换成 JSON 流;

  • 支持对枚举类型的序列化和反序列化;

  • 支持针对某些字段指定序列化为 null 值或不序列化;

  • 支持反序列化时自动转换数据类型。

Fastjson 2.x 版本 bug 修复

Fastjson 2.x 版本主要修复了以下重要的 bug:

  • 修复某些情况下可能会导致空指针异常的问题;

  • 解决某些情况下某些对象类型无法正确解析的问题;

  • 修复某些情况下 JSON 字符串中出现转义字符导致解析错误的问题;

  • 修复某些情况下无法正确地序列化枚举类型的问题。

Fastjson 3.x 版本特性

Fastjson 3.x 版本是 Fastjson 的最新版本,其特性包括:

  • 支持通过注解控制对象属性和 JSON 键的映射规则;

  • 支持自定义型转换器;

  • 支持注解指定日期格式;

  • 支持多环境下的自动引入依赖。

Fastjson 3.x 版本 bug 修复

Fastjson 3.x 版本主要修复了以下重要的 bug:

  • 修复某些情况下会导致 JSON 字符串乱码的问题;

  • 解决某些情况下某些对象类型无法正确解析的问题;

  • 修复某些情况下无法正确地序列化枚举类型的问题;

  • 修复某些情况下 JSON 解析会出现错误的问题。

需要注意的是,由于每个版本中存在大量的功能和 bug 修复,这里只对某些重要的特性和 bug 进行了概括介绍,更多的信息可以查看 Fastjson 的官方网站。


浏览 56
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报