`
brandNewUser
  • 浏览: 456073 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

alibaba fastjson的使用总结和心得

阅读更多

 

 

 
最初接触alibaba fastjson是由于其性能上的优势,对比原来采用codehause.jackson的解析,在hadoop平台上的手动转换对象有着将近1/3的性能提升,但随着开发应用越来越多,渐渐地也发现了在其他方面的强大之处,例如直接转化泛型(jackson对泛型的支持相对来说就比较差)。
 
Fastjson会自动处理对象中的泛型,将其解析成原来定义好的对象,建议一定要将泛型类型定义精确,以避免出现歧义,例如如果使用Map<String, Object> 就并不是一个定义良好的泛型,我们也并不知道Object对象真正表示的是什么,而fastjson解析Object时,由于不知道其具体类型,只能将其转化成JSONObject(结构类似一个Map,有着key和value)。
 

泛型类型解析

 
如果顶层类型中存在泛型,就会出现不知道确切类型的状况,因为Class是无法携带泛型信息的,Java中不存在一个类型为List<String>.class,如果这样使用,Fastjson会将对象解析成JSONObject。
 
alibaba fastjson提供了一套TypeReference相关的方法来解决这个问题,从源代码来看定义不是很长:
 
public class TypeReference<T> {

    private final Type type;

    protected TypeReference(){
        Type superClass = getClass().getGenericSuperclass();

        type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
    }

    public Type getType() {
        return type;
    }

    public final static Type LIST_STRING = new TypeReference<List<String>>() {}.getType();
}
 
 
构造函数中做了两件事,先从当前的Class.getGenericSuperclass,返回该Class表示的实体或直接超类的Type,重点在与,如果是参数化类型,返回的Type中会带上该类型,我们看一下这个方法的定义及其作用:
 

getGenericSuperclass

public Type getGenericSuperclass()

返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type

如果超类是参数化类型,则返回的 Type 对象必须准确反映源代码中所使用的实际类型参数。如果以前未曾创建表示超类的参数化类型,则创建这个类型。有关参数化类型创建过程的语义,请参阅 ParameterizedType 声明。如果此 Class 表示 Object 类、接口、基本类型或 void,则返回 null。如果此对象表示一个数组类,则返回表示 Object 类的 Class 对象。

 

返回:
此对象所表示的类的超类
抛出:
GenericSignatureFormatError - 如果常规类签名不符合 Java Virtual Machine Specification, 3rd edition 规定的格式
TypeNotPresentException - 如果常规超类引用不存在的类型声明
MalformedParameterizedTypeException - 如果常规超类引用的参数化类型由于某种原因无法实例化
从以下版本开始:
1.5
 
从文档中可以看出,如果其超类是参数化类型,返回的Type就为sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl类型,其继承自java.lang.reflect.ParameterizedType,用来表示参数化类型。
 
参数化类型中就可以从getActualTypeArguments中获取,因为TypeReference只有一个参数化类型定义,因此可以确定返回的数组肯定有一个元素(如果是Map就存在两个元素),这样type就为其参数化类型了,我们通过这个定义将对象的泛型传入至后续的json处理逻辑中。
 

getActualTypeArguments

Type[] getActualTypeArguments()

返回表示此类型实际类型参数的 Type 对象的数组。

注意,在某些情况下,返回的数组为空。如果此类型表示嵌套在参数化类型中的非参数化类型,则会发生这种情况。

 

返回:
表示此类型的实际类型参数的 Type 对象的数组
抛出:
TypeNotPresentException - 如果任何实际类型参数引用不存在的类型声明
MalformedParameterizedTypeException - 如果任何实际类型参数引用参数化类型,该类型出于某种原因无法被实例化
从以下版本开始:
1.5
 
所以使用该类的方法只有一种,就是继承,因此其构造方法为protected,只能允许子类来调用,在构造该对象时,就需要在声明最后加上{}来表示继承关系。
 
java.util.Map<java.lang.String, com.xxx.commons.json.test.JsonTest$InnerObj>
 
 
 
 

关于类型转换

 
如果是数组,由于某种对象的数组是存在对应的Class类型信息的,也就是说可以直接直接以Class的方式转换成功。
 
当时如果没有指定类型,就会转换成JSONObject,在其中以key/value的方式(类似Map)存储。
 
如果是数组,转成JSONArray,在其中包装JSONObject
 



 
 
 
如果我们使用TypeReference,指定其为List<String>,而List中其实是对象,那么直接转换成String,此时字符串就为json字符串。
 
如果事先不知道该json串的类型信息(json事先也无法知道其类型信息,而Java的序列化,是带类型信息的,因此携带的内容也要比json串丰富地多,耗费网络带宽也大),或者在Map中写不出统一的泛型,那么就会发生隐性的类型转换过程。在codehaus jackson中会将无法识别的json对象直接转换成Map(key,value)格式,如果是fastjson,则转换成JSONObject(其实也类似于json)。如果需要将该对象仍然转换成json格式,不会有任何问题,但如果想要以原来的对象方式操作它,就会出现问题了(因为没有对象信息,除非手动将其转换,但每部分都需要手写代码,比较麻烦)。
 
 
Map中字段为null不被持久化的问题
 
如果Map中的某个属性为null,并不会被持久化,可以参考
 
 
如果想让Map中的字段能够正常输出(这也是我们需要的),就需要在转换toJSONString时设置特殊的Feature来完成该功能:
 
JSON.toJSONString(object, SerializerFeature.WriteMapNullValue)
 
 

关于Feature

 
 
Fastjson中存在多种SerializerFeature,可以按照需要使用,例如
 
  • SerializerFeature.UseSingleQuotes,//支持单引号
  • SerializerFeature.WriteDateUseDateFormat,//日期格式化 
  • SerializerFeature.WriteMapNullValue, // 输出空置字段
  • SerializerFeature.WriteNullListAsEmpty, // list字段如果为null,输出为[],而不是null
  • SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null,输出为0,而不是null
  • SerializerFeature.WriteNullBooleanAsFalse, // Boolean字段如果为null,输出为false,而不是null
  • SerializerFeature.WriteNullStringAsEmpty // 字符类型字段如果为null,输出为"",而不是null
 
很多场景中,我们需要序列化的对象中存在循环引用,在许多的json库中,这会导致stackoverflow。在功能强大的fastjson中,你不需要担心这个问题。
 
使用@JSONField Annotation来定制化序列化字段的名称,还可以使用@JSONCreator来指定构造函数来创建对象,配合@JSONField来确定字段的名称。
 
如果使用新特性SerializerFeature.WriteClassName,可以在序列化的文本中加入@type信息,这样就可以进行合理的反序列化,因为知道了类型信息,可以通过默认的构造以及属性名称自动设置,此时反序列化的结果类似下面:
 
{"@type":"java.awt.Color","r":255,"g":0,"b":0,"alpha":255}
 
 
此时就可以进行自动识别,但此时输出的文本就会多出一倍的空间,因此如果有着明确的类型,不建议使用这种方式。
 
String text = ...; // {"@type":"java.awt.Color","r":255,"g":0,"b":0,"alpha":255}
Color color = (Color) JSON.parse(text);
 
 
这样可以解决一些序列化泛型中接口的问题,
 
还举例说明了可以使用组合类型,fastjson对这种结构的反序列化有专门支持:
 
String text = ...; // [{/* header */}, {/* body */}]
Type[] types = new  Type[] {Header.class, Body.class};
List<Object> list = JSON.parseArray(text, types);
Header header = (Header) list.get(0);
Body body = (Body) list.get(1);
 
 
在使用WriteClassName这个Feature来进行写Map等操作时,有一个问题,其中的List以及数组在被转化回来时无法识别,会被自动转换成JSONArray而不是原始的List,数组对象。如果用户原来使用的List,这个问题可以得到完美的解决,看一下JSONArray的定义,
 
/**
 * @author wenshao[szujobs@hotmail.com]
 */
public class JSONArray extends JSON implements List<Object>, Cloneable, RandomAccess, Serializable { 
 
可以对其进行强制转换List即可。
 
但是如果原始类型为数组类型,则只能够通过toArray方法,至于网友提出的能否直接使用Object[],其开发者给出了预期(只不过在1.2.9上也并未见其实现)。
 


 
 
但在1.2.9版本并没有看到这个Feature,所以还是拭目以待吧。
 
<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->
此外,我们在使用SpringMVC时,默认使用的json格式RequestMapper转换实现应该是jackson实现的,当然可以将其替换成fastjson的实现:
 
<bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
    <!-- HandlerAdapter -->
    <bean
        class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean
                    class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                    <property name="features">
                        <array value-type="com.alibaba.fastjson.serializer.SerializerFeature">
                            <value>WriteDateUseDateFormat</value>
                            <value>WriteMapNullValue</value>
                        </array>
                    </property>
                </bean>
            </list>
        </property>
    </bean>
  
 
 
 
 
  • 大小: 73.7 KB
  • 大小: 21.7 KB
分享到:
评论

相关推荐

    阿里巴巴 fastJson jar包

    综上所述,阿里巴巴的Fastjson jar包是Java开发中处理JSON数据的得力工具,它以其高性能、易用的API和强大的功能,深受广大开发者喜爱。无论是在小型项目还是大型系统中,都能发挥出显著的优势。

    阿里巴巴fastjson

    免费版阿里巴巴fastjson下载免费版阿里巴巴fastjson下载免费版阿里巴巴fastjson下载免费版阿里巴巴fastjson下载免费版阿里巴巴fastjson下载免费版阿里巴巴fastjson下载

    阿里巴巴fastjson的jar包

    总结来说,阿里巴巴的Fastjson是Java开发中处理JSON数据的得力工具,无论是在性能、易用性还是安全性方面,都展现出了优秀的特性。其丰富的API和功能,使得开发者能快速、高效地完成JSON与Java对象之间的转换,提升...

    阿里巴巴开源fastjson

    Fastjson,作为阿里巴巴开源的一款高效、功能强大的JSON库,它在Java开发领域中被广泛使用。JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其简洁明了的特性,深受开发者喜爱。Fastjson正是...

    阿里巴巴fastjson-1.2.83.jar

    阿里巴巴1.2.80及之前版本存在高危漏洞,已发布最新的1.2.83版本,供需要的各位下载使用。

    阿里巴巴json解析 fastjson.jar

    而阿里巴巴的Fastjson库,便是针对Java平台设计的一款高性能的JSON解析和生成工具,它以其高效、易用的特点,深受开发者喜爱。 一、Fastjson简介 Fastjson是阿里巴巴开源的一个Java语言编写的高性能功能完备的JSON...

    啊里巴巴FastJson jar包

    阿里巴巴的FastJson是一个高效、功能丰富的Java库,用于处理JSON数据。它提供了快速的性能,使得在Java应用程序中解析和生成JSON变得极其便捷。FastJson不仅适用于简单的JSON操作,还能应对复杂的JSON转换场景,广泛...

    fastjson-1.2.83.jar下载

    fastjson-1.2.83.jar下载,fastjson是阿里巴巴的开源JSON解析库,可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也支持从JSON字符串反序列化到JavaBean。fastjson采用全新的JSON解析算法,运行速度极快...

    fastjson-1.1.jar 阿里巴巴

    fastjson 阿里巴巴开发的,号称 解析json速度快。

    fastjson-阿里巴巴

    同时,阿里巴巴还会定期维护和更新Fastjson,确保其兼容性和稳定性。 总之,Fastjson作为阿里巴巴的优秀产品,凭借其高效的性能、易用的API和丰富的功能,已经成为Java开发者处理JSON数据的首选工具之一。无论是在...

    阿里fastjson.jar

    阿里Fastjson是一个高性能的Java JSON库,由阿里巴巴公司开发并维护。它被广泛应用于各种Java项目中,尤其在数据解析和序列化方面表现卓越。Fastjson的命名来源于"Fast Java Object to JSON",即快速地将Java对象...

    fastjson解析科大讯飞案例

    利用fastjson解析科大讯飞的听写json字符串,实现语音听写

    fastjson-1.2.74.jar和1.2.53两个版本

    2020最新的fastjson.jar,阿里开源的,非常好用,里面有两个版本,分别是1.2.53跟1.2.74两个版本,欢迎大家下载

    fastjson 1.2.6

    fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。 主要特点: 快速FAST (比其它任何基于Java的解析器和生成器更快,包括jackson) 强大(支持普通JDK类包括任意Java ...

    通过fastjson实现各种格式与json之间的转换

    通过fastjson实现了JavaBean,list,MAP,list等格式与json格式之间的转换,已经附带fastjson的包,包的版本为fastjson-1.1.36.jar

    fastjson-example:阿里巴巴fastjson示例。 一些演示以展示如何使用fastjson

    FastJson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。Github地址: 2.FastJson的特点: 1.速度快,无论序列化和反序列化,都...

    fastjson阿里巴巴公司推出的 强大json解析工具

    FASTJSON 阿里巴巴推出的 json解析工具

    阿里巴巴JSON的jar包 fastjson-1.1.40.jar

    阿里巴巴JSON的jar包 fastjson-1.1.40.jar。 免费下载阿里巴巴JSON的jar包,有什么不懂可以下面留言问我,亲测可用。我们公司做项目的时候经常用到,集成的东西挺多 阿里巴巴json

    fastjson.jar是阿里巴巴开发的jar包

    fastjson是阿里巴巴开发的jar包,fastjson-1.2.23.jar

    阿里fastjson

    阿里Fastjson是一个高性能的JSON库,它由阿里巴巴公司开发并维护,被广泛应用于Java和JavaScript开发环境中。Fastjson以其高效、轻量级和易用性而受到开发者的青睐,尤其在处理大量JSON数据时,其性能表现优异。下面...

Global site tag (gtag.js) - Google Analytics