介绍

FastJson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。

FastJson已经被广泛使用在各种场景,包括cache存储、RPC通讯、MQ通讯、网络协议通讯、Android客户端、Ajax服务器处理程序等等。

FastJson的API十分简洁。

String text = JSON.toJSONString(obj); //序列化
VO vo = JSON.parseObject("{...}", VO.class); //反序列化

JAR包下载

Maven依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>

JSON

com.alibaba.fastjson.JSON 这个类是FastJson API的入口,主要的功能都通过这个类提供。

String转JSON

对于字符串的处理,主要是看这个字符串(jsonStr)是JSON对象格式还是JSON数组格式,然后选择对应的方法处理就行。

JSON对象字符串转为JSON对象

JSONObject jsonObj = JSON.parseObject(jsonStr);

JSON数组字符串转为JSON数组

JSONArray jsonArr = JSON.parseArray(jsonStr);

String转JavaBean

Model model = JSON.parseObject(jsonStr, Model.class);

Object转String

包括JSONObject、JSONArray、JavaBean、数组、List、Set、Map都可以通过这种方式转String

String jsonStr = JSON.toJSONString(object);

JSONField

这是一个注解,用于配置在JavaBean,可以配置在getter/setter方法或者字段上,也可以直接配置在属性上。

注意:若属性是私有的,必须有set*方法。否则无法反序列化。

部分属性

@JSONField(ordinal=1)//配置序列化的字段顺序(1.1.42版本之后才支持)

@JSONField(serialize=false) //是否参与序列化:该字段不输出  但是如果加了final,这个字段就无法被过滤

@JSONField(derialize=false) //是否参与反序列化:该字段不输出  但是如果加了final,这个字段就无法被过滤 

@JSONField(format="yyyy-MM-dd HH:mm:ss") //日期按照指定格式序列化

@JSONField(name="别名");//使用字段别名

@JSONField(serialzeFeatures={SerialzeFeatures属性});//序列化规则

@JSONField(parseFeatures={Features属性});//反序列化规则

SerializerFeature属性

public enum SerializerFeature {
/**
* 输出key时是否使用双引号,默认为true
*/
QuoteFieldNames,
/**
* 使用单引号而不是双引号,默认为false
*/
UseSingleQuotes,
/**
* 是否输出值为null的字段,默认为false
*/
WriteMapNullValue,
/**
* 用枚举toString()值输出
*/
WriteEnumUsingToString,
/**
* 用枚举name()输出
*/
WriteEnumUsingName,
/**
* Date使用ISO8601格式输出,默认为false
*/
UseISO8601DateFormat,
/**
* @since 1.1
* List字段如果为null,输出为[],而非null
*/
WriteNullListAsEmpty,
/**
* @since 1.1
* 字符类型字段如果为null,输出为"",而非null
*/
WriteNullStringAsEmpty,
/**
* @since 1.1
* 数值字段如果为null,输出为0,而非null
*/
WriteNullNumberAsZero,
/**
* @since 1.1
* Boolean字段如果为null,输出为false,而非null
*/
WriteNullBooleanAsFalse,
/**
* @since 1.1
* 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true
*/
SkipTransientField,
/**
* @since 1.1
* 按字段名称排序后输出。默认为false
*/
SortField,
/**
* @since 1.1.1
* 把\t做转义输出,默认为false(不推荐,已删除)
*/
@Deprecated
WriteTabAsSpecial,
/**
* @since 1.1.2
* 结果是否格式化,默认为false
*/
PrettyFormat,
/**
* @since 1.1.2
* 序列化时写入类型信息,默认为false。反序列化时需用到
*/
WriteClassName,
/**
* @since 1.1.6
* 消除对同一对象循环引用的问题,默认为false
*/
DisableCircularReferenceDetect,
/**
* @since 1.1.9
* 对斜杠"/"进行转义
*/
WriteSlashAsSpecial,
/**
* @since 1.1.10
* 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false
*/
BrowserCompatible,
/**
* @since 1.1.14
* 全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);
*/
WriteDateUseDateFormat,
/**
* @since 1.1.15
*/
NotWriteRootClassName,
/**
* @since 1.1.19
* 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false
*/
DisableCheckSpecialChar,
/**
* @since 1.1.35
* 将对象转为array输出
*/
BeanToArray,
/**
* @since 1.1.37
*/
WriteNonStringKeyAsString,
/**
* @since 1.1.42
*/
NotWriteDefaultValue,
/**
* @since 1.2.6
*/
BrowserSecure,
/**
* @since 1.2.7
*/
IgnoreNonFieldGetter,
/**
* @since 1.2.9
*/
WriteNonStringValueAsString,
/**
* @since 1.2.11
*/
IgnoreErrorGetter; }

Feature属性

public enum Feature {
/**
* 这个特性,决定了解析器是否将自动关闭那些不属于parser自己的输入源。
* 如果禁止,则调用应用不得不分别去关闭那些被用来创建parser的基础输入流InputStream和reader;
* 如果允许,parser只要自己需要获取closed方法(当遇到输入流结束,或者parser自己调用 JsonParder#close方法),就会处理流关闭。
* 注意:这个属性默认是true,即允许自动关闭流
*/
AutoCloseSource,
/**
* 该特性决定parser将是否允许解析使用Java/C++ 样式的注释(包括'/'+'*' 和'//' 变量)。
* 由于JSON标准说明书上面没有提到注释是否是合法的组成,所以这是一个非标准的特性;尽管如此,这个特性还是被广泛地使用。
* 注意:该属性默认是false,因此必须显式允许,即通过JsonParser.Feature.ALLOW_COMMENTS 配置为true。
*/
AllowComment,
/**
* 这个特性决定parser是否将允许使用非双引号属性名字, (这种形式在Javascript中被允许,但是JSON标准说明书中没有)。
* 注意:由于JSON标准上需要为属性名称使用双引号,所以这也是一个非标准特性,默认是false的。
* 同样,需要设置JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES为true,打开该特性。
*/
AllowUnQuotedFieldNames,
/**
* 该特性决定parser是否允许单引号来包住属性名称和字符串值。
* 注意:默认下,该属性也是关闭的。需要设置JsonParser.Feature.ALLOW_SINGLE_QUOTES为true
*/
AllowSingleQuotes,
/**
* 该特性决定JSON对象属性名称是否可以被String#intern 规范化表示。如果允许,则JSON所有的属性名将会 intern() ;
* 如果不设置,则不会规范化,默认下,该属性是开放的。此外,必须设置CANONICALIZE_FIELD_NAMES为true
* 关于intern方法作用:当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串 (该对象由 equals(Object) 方法确定),则返回池中的字符串。
* 否则,将此 String 对象添加到池中, 并且返回此 String 对象的引用。
*/
InternFieldNames,
/**
* 这个设置为true则遇到字符串符合ISO8601格式的日期时,会直接转换成日期类。
*/
AllowISO8601DateFormat,
/**
* 允许多重逗号,如果设为true,则遇到多个逗号会直接跳过。
* {"a":1,,,"b":2}
*/
AllowArbitraryCommas,
/**
* 这个设置为true则用BigDecimal类来装载数字,否则用的是double;
*/
UseBigDecimal,
/**
* @since 1.1.2
* 忽略不匹配
*/
IgnoreNotMatch,
/**
* @since 1.1.3
* 如果你用fastjson序列化的文本,输出的结果是按照fieldName排序输出的,parser时也能利用这个顺序进行优化读取。这种情况下,parser能够获得非常好的性能
*/
SortFeidFastMatch,
/**
* @since 1.1.3
* 禁用ASM
*/
DisableASM,
/**
* @since 1.1.7
* 禁用循环引用检测
*/
DisableCircularReferenceDetect,
/**
* @since 1.1.10
* 对于没有值的字符串属性设置为空串
*/
InitStringFieldAsEmpty,
/**
* @since 1.1.35
* 支持数组to对象
*/
SupportArrayToBean,
/**
* @since 1.2.3
* 属性保持原来的顺序
*/
OrderedField,
/**
* @since 1.2.5
* 禁用特殊字符检查
*/
DisableSpecialKeyDetect, /**
* @since 1.2.9
* 使用对象数组
*/
UseObjectArray; }

测试代码

目标JavaBean代码:

class User {

    //指定序列化字段顺序,字段名称
@JSONField(ordinal=4,name="ID")
private Integer id; //指定序列化字段顺序,不参加序列化
@JSONField(ordinal=3,serialize=false)
private String name; //指定序列化字段顺序,不参加反序列化
@JSONField(ordinal=2,deserialize=false)
private Integer age; //指定序列化字段顺序,日期格式
@JSONField(ordinal=1,format="yyyy-MM-dd")
private Date creattime; //指定序列化规则,字段为null的时候依然参加序列化
@JSONField(serialzeFeatures=SerializerFeature.WriteMapNullValue)
private String phone; public Integer getId() {return id;}
public Date getCreattime() {return creattime;}
public void setId(Integer id) {this.id = id;}
public void setCreattime(Date creattime) {this.creattime = creattime;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Integer getAge() {return age;}
public void setAge(Integer age) {this.age = age;}
public String getPhone() {return phone;}
public void setPhone(String phone) {this.phone = phone;} @Override
public String toString() {
return "id="+id+"; name="+name+"; age="+age+"; createtime="+creattime;
} };

测试代码:

User user = new User();
user.setId(123456);
user.setName("wangbo");
user.setAge(28);
user.setCreattime(new Date()); String userStr = JSON.toJSONString(user);
System.out.println(userStr); User user2 = JSON.parseObject(userStr, User.class);
System.out.println(user2);

执行结果:

userStr

{"phone":null,"creattime":"2018-12-04","age":28,"ID":123456}

user2

id=123456; name=null; age=null; createtime=Tue Dec 04 00:00:00 CST 2018

可以看出:

第一步序列化的结果:按照指定字段顺序序列化的,id字段序列化为ID,name没有参加序列化,createtime按照指定格式序列化,phone为null,但是参与了序列化。

(FastJson默认的序列化规则是字段的值为null的时候,不参与序列化,serialzeFeatures=SerializerFeature.WriteMapNullValue可以在value的值为null的时候,依然会把它的值序列化出来。)

第二部反序列化结果:age没有参与反序列化。

JSONPath

FastJson 1.2.0之后的版本支持JSONPath。这是一个很强大的功能,可以在java框架中当作对象查询语言(OQL)来使用。

API

public class JSONPath {

    //求值,静态方法
public static Object eval(Object rootObject, String path); //计算size,Map非空元素个数,对象非空元素个数,Collection的Size,数组的长度。其他无法求值返回-1
public static int size(Object rootObject, String path); //是否包含,path中是否存在对象
public static boolean contains(Object rootObject, String path); //是否包含,path中是否存在指定值,如果是集合或者数组,在集合中查找value是否存在
public static boolean containsValue(Object rootObject, String path, Object value); //在数组或者集合中添加元素
public static void arrayAdd(Object rootObject, String path, Object... values); //修改制定路径的值,如果修改成功,返回true,否则返回false
public static boolean set(Object rootObject, String path, Object value); }

语法

JSONPATH 描述
$ 根对象,例如$.name
[num] 数组访问,其中num是数字,可以是负数。例如$[0].leader.departments[-1].name
[num0,num1,num2...] 数组多个元素访问,其中num是数字,可以是负数,返回数组中的多个元素。例如$[0,3,-2,5]
[start:end] 数组范围访问,其中start和end是开始小表和结束下标,可以是负数,返回数组中的多个元素。例如$[0:5]
[start:end :step] 数组范围访问,其中start和end是开始小表和结束下标,可以是负数;step是步长,返回数组中的多个元素。例如$[0:5:2]
[?(key)] 对象属性非空过滤,例如$.departs[?(name)]
[key > 123] 数值类型对象属性比较过滤,例如$.departs[id >= 123],比较操作符支持=,!=,>,>=,<,<=
[key = '123'] 字符串类型对象属性比较过滤,例如$.departs[name = '123'],比较操作符支持=,!=,>,>=,<,<=
[key like 'aa%'] 字符串类型like过滤,
例如$.departs[name like 'sz*'],通配符只支持% 
支持not like
[key rlike 'regexpr'] 字符串类型正则匹配过滤,
例如departs[name like 'aa(.)*'],
正则语法为jdk的正则语法,支持not rlike
[key in ('v0', 'v1')] IN过滤, 支持字符串和数值类型 
例如: 
$.departs[name in ('wenshao','Yako')] 
$.departs[id not in (101,102)]
[key between 234 and 456] BETWEEN过滤, 支持数值类型,支持not between 
例如: 
$.departs[id between 101 and 201]
$.departs[id not between 101 and 201]
length() 或者 size() 数组长度。例如$.values.size() 
支持类型java.util.Map和java.util.Collection和数组
. 属性访问,例如$.name
.. deepScan属性访问,例如$..name
* 对象的所有属性,例如$.leader.*
['key'] 属性访问。例如$['name']
['key0','key1'] 多个属性访问。例如$['id','name']

注意:以下两种写法的语义是相同的:

$.store.book[0].title
$['store']['book'][0]['title']

语法示例

JSONPath 语义
$ 根对象
$[-1] 最后元素
$[:-2] 第1个至倒数第2个
$[1:] 第2个之后所有元素
$[1,2,3] 集合中1,2,3个元素

代码示例

package com.wangbo.fastjson;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath; public class Test { public static void main(String[] args) {
String jsonStr = "{\n" +
" \"store\": {\n" +
" \"bicycle\": {\n" +
" \"color\": \"red\",\n" +
" \"price\": 19.95\n" +
" },\n" +
" \"book\": [\n" +
" {\n" +
" \"author\": \"刘慈欣\",\n" +
" \"price\": 8.95,\n" +
" \"category\": \"科幻\",\n" +
" \"title\": \"三体\"\n" +
" },\n" +
" {\n" +
" \"author\": \"itguang\",\n" +
" \"price\": 12.99,\n" +
" \"category\": \"编程语言\",\n" +
" \"title\": \"go语言实战\"\n" +
" }\n" +
" ]\n" +
" }\n" +
"}"; JSONObject jsonObject = JSON.parseObject(jsonStr); System.out.println(jsonObject.toString()); //得到所有的书
List<Book> books = (List<Book>) JSONPath.eval(jsonObject, "$.store.book");
System.out.println("books=" + books); //得到所有的书名
List<String> titles = (List<String>) JSONPath.eval(jsonObject, "$.store.book.title");
System.out.println("titles=" + titles); //第一本书title
String title = (String) JSONPath.read(jsonStr, "$.store.book[0].title");
System.out.println("title=" + title); //price大于10元的book
List<Book> list = (List<Book>) JSONPath.read(jsonStr, "$.store.book[price > 10]");
System.out.println("price大于10元的book="+ list); //price大于10元的title
List<String> list2 =(List<String>) JSONPath.read(jsonStr, "$.store.book[price > 10].title");
System.out.println("price大于10元的title=" + list2); //category(类别)为科幻的book
List<Book> list3 = (List<Book>) JSONPath.read(jsonStr,"$.store.book[category = '科幻']");
System.out.println("category(类别)为科幻的book=" + list3); //bicycle的所有属性值
Collection<String> values = (Collection<String>) JSONPath.eval(jsonObject, "$.store.bicycle.*");
System.out.println("bicycle的所有属性值={}" + values); //bicycle的color和price属性值
List<String> read =(List<String>) JSONPath.read(jsonStr, "$.store.bicycle['color','price']");
System.out.println("bicycle的color和price属性值=" + read); } }

运行结果

{"store":{"bicycle":{"color":"red","price":19.95},"book":[{"author":"刘慈欣","price":8.95,"category":"科幻","title":"三体"},{"author":"itguang","price":12.99,"category":"编程语言","title":"go语言实战"}]}}
books=[{"author":"刘慈欣","price":8.95,"category":"科幻","title":"三体"},{"author":"itguang","price":12.99,"category":"编程语言","title":"go语言实战"}]
titles=["三体","go语言实战"]
title=三体
price大于10元的book=[{"author":"itguang","price":12.99,"category":"编程语言","title":"go语言实战"}]
price大于10元的title=["go语言实战"]
category(类别)为科幻的book=[{"author":"刘慈欣","price":8.95,"category":"科幻","title":"三体"}]
bicycle的所有属性值={}[red, 19.95]
bicycle的color和price属性值=[red, 19.95]

Alibaba FastJson 常用方法使用指南的更多相关文章

  1. alibaba fastjson List<Map<String, String>>2Str

    import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; impo ...

  2. Alibaba FastJson

    import com.alibaba.fastjson.JSON import com.alibaba.fastjson.JSONObject class Test { static main(arg ...

  3. 全解史上最快的JOSN解析库 - alibaba Fastjson

    JSON,全称:JavaScript Object Notation,作为一个常见的轻量级的数据交换格式,应该在一个程序员的开发生涯中是常接触的.简洁和清晰的层次结构使得 JSON 成为理想的数据交换 ...

  4. JAVA中使用alibaba fastjson实现JSONObject、Object、Json字符串的转换

    JAVA中使用alibaba fastjson实现JSONObject.Object.Json字符串的转换 Object转JSON字符串:String jsonStr = JSONObject.toJ ...

  5. fastJson常用方法总结

    1.了解json json就是一串字符串 只不过元素会使用特定的符号标注. {} 双括号表示对象 [] 中括号表示数组 "" 双引号内是属性或值 : 冒号表示后者是前者的值(这个值 ...

  6. 探索RequestBody报com.alibaba.fastjson.JSONObject cannot be cast to xxx

    今天使用RequestBody接受前端传过来的参数,以前接受字符串数组非常成功,这次把形参改成了List<User>,原本以为顺利接受参数并映射成User的list结构,结果竟然在我取us ...

  7. 42-字符串到json 的错误 com.alibaba.fastjson.JSONObject cannot be cast to java.lang.String

    json: {"updated_at":1551780617,"attr":{"uptime_h":3,"uptime_m&quo ...

  8. com.alibaba.fastjson.JSON对类对象的序列化与反序列化

    1. 目标 把类的对象存储到字符串可存储 2. 类定义 public interface JsonInterface { } mport com.alibaba.fastjson.JSON; impo ...

  9. Json和Map互转,四个包(org.json/net.sf.json/com.google.gson/com.alibaba.fastjson)

    目前使用的(org.json/net.sf.json/com.google.gson/com.alibaba.fastjson)这四种json-map互转,其他的以后在补充.............. ...

随机推荐

  1. Python中__init__和self的意义和作用

    由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去.以学生类为例,通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑 ...

  2. scrapy 爬取前程无忧

    spider # -*- coding: utf-8 -*- import scrapy from Jobs.items import JobsItem class Job51spiderSpider ...

  3. NC 自定义项参照设置为查询条件

    select * from pub_query_condition where pk_templet in (select id from pub_query_templet where node_c ...

  4. http 自定义信息头(header)设置与获取

    一.后端设置(如:java) 在你服务端(如:java)返回的时候写上: res.setHeader("Access-Control-Expose-Headers",propNam ...

  5. 给area标签添加红色边框

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org ...

  6. javaMail的使用以及trying to connect to host "1xxx@163.com", port 25, isSSL false异常

    最近项目用到邮件系统,开始了解javaMail...话不多说先上代码: pom依赖: <!--    邮件  https://mvnrepository.com/artifact/javax.m ...

  7. (PMP)解题技巧和典型题目分析(每日20题)

    3.11 1.A(C),2.D,3.A,4.B,5.A(C),6.D(A),7.D,8.A(D),9.B,10.D(B), 11.C(B),12.C(D),13.B,14.D,15.C,16.C(D) ...

  8. centos7安装ceph-luminous(1 mon+2 osd)

    说明:由于环境有限,这里只是用一台机器 一.部署环境 VMware Workstation 10 centos7 二.主机配置 主机名 ip cpu ram master 192.168.137.10 ...

  9. DOTween的基本用法

    首先声明一点,不要简单的认为 DOTween 只能用在 Transform 组件上完成一些简单的动画,或者是完成一些 UI 动画,DOTween 的用途是很广的,unity中有很多组件都可以使用 DO ...

  10. Day08 (黑客成长日记) 命名空间和作用域

    Day08:命名空间和作用域: 1.命名空间: (1)内置命名空间(python解释器): 就是python解释器一旦启动就可以使用的名字储存在内置命名空间中: eg: len() print() a ...