首页 > 其他分享 >[JSON] Fastjson 之版本对比:Fastjson vs Fastjson2

[JSON] Fastjson 之版本对比:Fastjson vs Fastjson2

时间:2023-11-07 14:47:09浏览次数:33  
标签:Fastjson fastjson2 String JSONObject alibaba JSON Fastjson2 com

1 Fastjson2

1.1 简述

  • FASTJSON相对其他JSON库的特点是,从2011年fastjson发布1.1.x版本之后,其性能从未被其他Java实现的JSON库超越。

  • Fastjson2相对Fastjson1版本可以说是一次完全重构

    • 这里从代码的角度,分析两者的一些区别;
    • 并总结一些新的,让小伙伴们使用Fastjson2或者进行功能扩展的时候,能更加顺畅。
    • 除了在性能方面的提升之外,Fastjson 2还解决了一系列安全方面的问题和兼容性的问题,这很大的提高了使用的便捷性
  • FASTJSON v2是FASTJSON项目的重要升级,目标是为下一个十年提供一个高性能的JSON库

  • 通过同一套API:

    • 支持JSON/JSONB两种协议;
    • JSONPath 是一等公民;
    • 支持全量解析部分解析
    • 支持Java服务端客户端Android、大数据场景;支持Kotlin
    • 支持JSON Schema
    • 支持Graal Native-Image

1.2 安全漏洞问题

1.2.1 罪魁祸首 AutoType

fastjson、jackson 都支持 AutoType 功能,这个功能在序列化的 JSON 字符串中带上类型信息,在反序列化时,不需要传入类型,实现自动类型识别

1.2.2 Fastjson V1

fastjson 1.x 内部维护了一个AutoType白名单,java 发展近 30 年难免有些漏网之鱼,这也造成近几年 fastjson 安全漏洞频发。

1.2.3 Fastjson V2

  • fastjson2 AutoType 必须显式打开才能使用,没有任何白名单,也不包括任何 Exception 类的白名单。这可以保证缺省配置下是安全的
  • 序列化时带上类型信息,需要使用 JSONWriter.Feature.WriteClassName。比如:
Bean bean = ...;
String jsonString = JSON.toJSONString(bean, JSONWriter.Feature.WriteClassName);
  • 很多时候,root对象是可以知道类型的,里面的对象字段是基类或者不确定类型,这个时候不输出root对象的类型信息,可以减少序列化结果的大小,也能提升反序列化的性能。
Bean bean = ...;
String jsonString = JSON.toJSONString(bean, JSONWriter.Feature.WriteClassName, JSONWriter.Feature.NotWriteRootClassName);
  • 反序列化打开AutoType功能支持自动类型
Bean bean = (Bean) JSON.parseObject(jsonString, Object.class, JSONReader.Feature.SupportAutoType);
  • fastjson2 AutoType 支持配置 safeMode,在 safeMode 打开后,显式传入 AutoType 参数也不起作用,具体配置如下:
-Dfastjson2.parser.safeMode=true
  • fastjson2 AutoType 会经过内置黑名单过滤。
    • 虽然该黑名单能拦截大部分常见风险,但是这个机制不能保证绝对安全
    • 故:打开 AutoType 【不应该】在暴露在公网的场景下使用

2 版本对比

2.1 引入依赖

  • V1

https://github.com/alibaba/fastjson/releases
https://repo1.maven.org/maven2/com/alibaba/fastjson/

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

截止 2023-11-07 的最新版本为 1.2.83

  • V2

https://github.com/alibaba/fastjson2/releases
https://repo1.maven.org/maven2/com/alibaba/fastjson2/fastjson2/

<dependency>
	<groupId>com.alibaba.fastjson2</groupId>
	<artifactId>fastjson2</artifactId>
	<version>2.0.42</version>
</dependency>

截止 2023-11-07 的最新版本为 2.0.42

注意:groupId 和v1版本的相比,有所改变。

官方说明:如果原来使用fastjson 1.2.x版本,可以使用兼容包,兼容包不能保证100%兼容,请仔细测试验证,发现问题请及时反馈。兼容包坐标如下:

  • 兼容包
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>2.0.1</version>
</dependency>

2.2 源码对比

2.2.1 整体继承类的修改

在fastjson 2.0中,package和1.x不一样,是com.alibaba.fastjson2。如果你之前用的是fastjson1,大多数情况直接更换包名就即可。

V1

//1.Fastjson 1 JSONObject类定义
public class JSONObject extends JSON implements Map<String,Object> ... {

}

//2.Fastjson 1 JSONArray类定义
public class JSONArray extends JSON implements List<Object> ... {

}

V2

//1.Fastjson2 JSONObject类定义
public class JSONObject extends LinkedHashMap<String, Object> implements InvocationHandler {

}

//2.Fastjson2 JSONArray类定义
public class JSONArray extends ArrayList<Object> {

}

Fastjson2JSONObject 实现了链结构的Map,是有序的Map容器
无论是JSONObject或者JSONArray都摆脱了JSON的类,使JSON由抽象类变成了接口。

package com.alibaba.fastjson2;

class JSON {
    // 将字符串解析成JSONObject
    static JSONObject parseObject(String str);
    
    // 将字符串解析成JSONArray
    static JSONArray parseArray(String str);
    
    // 将字符串解析成Java对象
    static T parseObject(byte[] utf8Bytes, Class<T> objectClass);

    // 将Java对象输出成字符串
    static String toJSONString(Object object);
    
    // 将Java对象输出成UT8编码的byte[]
    static byte[] toJSONBytes(Object object);
}

class JSONB {
    // 将jsonb格式的byte[]解析成Java对象
    static T parseObject(byte[] jsonbBytes, Class<T> objectClass);
    
    // 将Java对象输出成jsonb格式的byte[]
    static byte[] toBytes(Object object);
}

class JSONObject {
    Object get(String key);
    int getIntValue(String key);
    Integer getInteger(String key);
    long getLongValue(String key);
    Long getLong(String key);
    T getObject(String key, Class<T> objectClass);
    
    // 将JSONObject对象转换为Java对象
    T toJavaObject(Class<T> objectClass);
}

class JSONArray {
    Object get(int index);
    int getIntValue(int index);
    Integer getInteger(int index);
    long getLongValue(int index);
    Long getLong(int index);
    T getObject(int index, Class<T> objectClass);
}

class JSONPath {
    // 构造JSONPath
    static JSONPath of(String path);

    // 根据path直接解析输入,会部分解析优化,不会全部解析
    Object extract(JSONReader jsonReader);
    
    // 根据path对对象求值
    Object eval(Object rootObject);
}

class JSONReader {
    // 构造基于String输入的JSONReader
    static JSONReader of(String str);
    
    // 构造基于ut8编码byte数组输入的JSONReader
    static JSONReader of(byte[] utf8Bytes);
    
    // 构造基于char[]输入的JSONReader
    static JSONReader of(char[] chars);
    
    // 构造基于json格式byte数组输入的JSONReader
    static JSONReader ofJSONB(byte[] jsonbBytes)
}

2.2.2 常见类型的优化

  • 时间转化类由原来使用SimpleDateFormat转化为 JDK8 提供的java.time API,吸收了 joda-time的部分精华,功能更强大,性能也更好。
  • 同时,DateTimeFormatter线程安全的。

3 常见使用

3.1 案例:将JSON字符串解析为JSONObject

String text = "...";
JSONObject data = JSON.parseObject(text);

byte[] bytes = ...;
JSONObject data = JSON.parseObject(bytes);

3.2 案例:将JSON字符串解析为JSONArray

String text = "...";
JSONArray data = JSON.parseArray(text);

3.3 案例:将JSON字符串解析为Java对象

String text = "...";
User data = JSON.parseObject(text, User.class);

3.4 案例:将Java对象序列化为JSON字符串

Object data = "...";
String text = JSON.toJSONString(data);
byte[] text = JSON.toJSONBytes(data);

3.5 案例:使用JSONObject、JSONArray

String jsonText = "{\"id\": 2,\"name\": \"fastjson2\"}";
JSONObject obj = JSON.parseObject(jsonText);

int id = obj.getIntValue("id");
String name = obj.getString("name");
String text = "[2, \"fastjson2\"]";

JSONArray array = JSON.parseArray(text);
int id = array.getIntValue(0);
String name = array.getString(1);

X 参考文献

标签:Fastjson,fastjson2,String,JSONObject,alibaba,JSON,Fastjson2,com
From: https://www.cnblogs.com/johnnyzen/p/17814937.html

相关文章

  • 使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为
    一个报表的查询,用ajax调用的Service,查询条件没有问题,后台也能返回数据,就一直返回Error提示,F12看到是因为返回json时出错了 在web.config的configuration加以下代码即可解决<system.web.extensions><scripting><webServices><jsonSerializationmaxJs......
  • C#解析JSON字符串总结
    JSON文件读取到内存中就是字符串,.NET操作JSON就是生成与解析JSON字符串。操作JSON通常有以下几种方式:1.原始方式:按照JSON字符串自己来解析。 2.通用方式【★★★★★】:这种方式是使用开源的类库Newtonsoft.Json(下载地址http://json.codeplex.com/)。下载后添加dll引用就......
  • java object 转为 json
      JSONObjectjsonObject=JSONObject.fromObject(map)执行到这的时候没有任何反应的原因及解决办法 JSONObject,JSONArray使用手册http://www.open-open.com/lib/view/open1391842371442.html JSONObject.fromObject(map)(JSON与JAVA数据的转换) 使用JSON时,除了要导入JSON网站上......
  • Newtonsoft.Json基本用法
    序列化和反序列化JSONJsonConvert对于想要与JSON字符串相互转换的简单场景,JsonConvert上的SerializeObject ()和 DeserializeObject () 方法在JsonSerializer上提供了易于使用的包装器。下面代码使用序列化与反序列化:1classProduct2{3[JsonIgnore]4......
  • Python-geojson转shp 工具
    工具使用演示: ......
  • 通过@JsonFormat和@DateTimeFormat,解决前后端时间格式问题
    在domain层的时间属性上面加@JsonFormat和@DateTimeFormat注解后端传前端:GMT+8:表示东八区@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss",timezone="GMT+8")前端传后端:@DateTimeFormat(pattern="yyyy-MM-ddHH:mm......
  • 通过@JsonFormat和@DateTimeFormat,解决前后端时间格式问题
    在domain层的时间属性上面加@JsonFormat和@DateTimeFormat注解后端传前端:GMT+8:表示东八区@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss",timezone="GMT+8")前端传后端:@DateTimeFormat(pattern="yyyy-MM-ddHH:mm......
  • js把json字符串转成json数组
    如何将JSON字符串转换为JSON数组。假设你有以下JSON字符串,它表示一个简单的数组,其中包含两个对象:'[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]'要将这个JSON字符串转换为JavaScript中的数组对象,你可以使用JSON.parse()方法。这个方法接受一个J......
  • js怎么把json字符串转化为一个对象
    在JavaScript中,如果你有一个JSON字符串,你可以使用JSON.parse()方法将其转换成一个JavaScript对象。例如,如果你有以下的JSON字符串:'{"id":1,"name":"Alice"}'你可以使用以下的代码将其转换成一个JavaScript对象://JSON字符串varjsonString='{"id":1,"name"......
  • NodeJS系列(13)- Next.js 框架 (六) | Node.js + Next.js + Prisma/Sequelize (ORM) + M
    Next.js是一个用于构建Web应用程序的框架。Next.js是一个用于生产环境的React框架,是一个React服务端渲染应用框架。NextJS:https://nextjs.org/Prisma是一个基于promise的Node.js和TypeScript的ORM,目前支持Mysql,MariaDB,SQLite,PostgreSQL,AWSAuroraServerles......