Fastjson介紹
文章導讀 [隱藏]
簡介
Fastjson是一個Java語言編寫的高性能功能完善的JSON庫。由阿里巴巴
高性能
fastjson采用獨創的算法,將parse的速度提升到極致,超過所有json庫,包括曾經號稱最快的jackson。并且還超越了google的二進制協議protocol buf。
支持標準
Fastjson完全支持http://json.org的標準,也是官方網站收錄的參考實現之一。
功能強大
支持各種JDK類型。包括基本類型、JavaBean、Collection、Map、Enum、泛型等。
支持循環引用
無依賴
不需要例外額外的jar,能夠直接跑在JDK上。
支持范圍廣
支持JDK 5、JDK 6、Android、阿里云手機等環境。
開源
Apache License 2.0
代碼托管在github.org上,項目地址是 https://github.com/AlibabaTech/fastjson
測試充分
fastjson有超過1500個testcase,每次構建都會跑一遍,豐富的測試場景保證了功能穩定。
下載
http://code.alibabatech.com/mvn/releases/com/alibaba/fastjson/
背景:剛接觸這個開源項目不久。遇到問題也不少。不過通過各方詢問、及源碼探究開源得到解決。最近使用FastJson結合hibernate做項目,發現關于對象的級聯屬性的過濾上用的不是很順。當然簡單的屬性過濾 @溫少 已經提供了 SimplePropertyPreFilter 使用,使用方法有詳細說明的。這里我針對級聯屬性的過濾對該類做了補充。(當然你也可以使用注解實現)
ok、上代碼:
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.suncompass.example.auth.entity.AuthEmployee;
import com.suncompass.example.auth.entity.AuthMenu;
import com.suncompass.framework.base.entity.BaseEntity;
/**
* @author :晨風²º¹³ <br>
* @Comment : fastjson 針對類型的屬性選擇過濾器(可以跨層級) <br>
*/
public class ComplexPropertyPreFilter implements PropertyPreFilter {
private Map<Class<?>, String[]> includes = new HashMap<>();
private Map<Class<?>, String[]> excludes = new HashMap<>();
static {
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
}
public ComplexPropertyPreFilter() {
}
public ComplexPropertyPreFilter(Map<Class<?>, String[]> includes) {
super();
this.includes = includes;
}
public boolean apply(JSONSerializer serializer, Object source, String name) {
//對象為空。直接放行
if (source == null) {
return true;
}
// 獲取當前需要序列化的對象的類對象
Class<?> clazz = source.getClass();
// 無需序列的對象、尋找需要過濾的對象,可以提高查找層級
// 找到不需要的序列化的類型
for (Map.Entry<Class<?>, String[]> item : this.excludes.entrySet()) {
// isAssignableFrom(),用來判斷類型間是否有繼承關系
if (item.getKey().isAssignableFrom(clazz)) {
String[] strs = item.getValue();
// 該類型下 此 name 值無需序列化
if (isHave(strs, name)) {
return false;
}
}
}
// 需要序列的對象集合為空 表示 全部需要序列化
if (this.includes.isEmpty()) {
return true;
}
// 需要序列的對象
// 找到不需要的序列化的類型
for (Map.Entry<Class<?>, String[]> item : this.includes.entrySet()) {
// isAssignableFrom(),用來判斷類型間是否有繼承關系
if (item.getKey().isAssignableFrom(clazz)) {
String[] strs = item.getValue();
// 該類型下 此 name 值無需序列化
if (isHave(strs, name)) {
return true;
}
}
}
return false;
}
/*
* 此方法有兩個參數,第一個是要查找的字符串數組,第二個是要查找的字符或字符串
*/
public static boolean isHave(String[] strs, String s) {
for (int i = 0; i < strs.length; i++) {
// 循環查找字符串數組中的每個字符串中是否包含所有查找的內容
if (strs[i].equals(s)) {
// 查找到了就返回真,不在繼續查詢
return true;
}
}
// 沒找到返回false
return false;
}
public Map<Class<?>, String[]> getIncludes() {
return includes;
}
public void setIncludes(Map<Class<?>, String[]> includes) {
this.includes = includes;
}
public Map<Class<?>, String[]> getExcludes() {
return excludes;
}
public void setExcludes(Map<Class<?>, String[]> excludes) {
this.excludes = excludes;
}
public static void main(String[] args) {
// use instanceOf,用來判斷對象是否是類的實例
// use isAssignableFrom(),用來判斷類型間是否有繼承關系
// use isInstance(),用來判斷對象是否是類的實例
Class<?> intClass = Integer.class;
// Create various objects.
String str = "Hello";
Date date = new Date();
Integer i = new Integer(10);
// Is str an instance of class Integer?
boolean check1 = intClass.isInstance(str);
System.out.println("str is an Integer? " + check1);
// Is date an instance of class Integer?
boolean check2 = intClass.isInstance(date);
System.out.println("date is an Integer? " + check2);
// Is i an instance of class Integer?
boolean check3 = intClass.isInstance(i);
System.out.println("i is an Integer? " + check3);
System.out.println(BaseEntity.class.isInstance(new AuthEmployee()));
System.out.println(AuthEmployee.class.isInstance(new AuthMenu()));
System.out.println(BaseEntity.class.isAssignableFrom(AuthEmployee.class));
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.example.util.fastjson.ComplexPropertyPreFilter;
public class A {
private Integer aid;
private B b;
private List<C> c = new ArrayList<>();
public A() {
super();
}
public static void main(String[] args) {
A a = new A();
a.setAid(1);
B b = new B();
b.setBid(2);
a.setB(b);
b.setA(a);
C c = new C();
c.setId(3);
a.getC().add(c);
b.getC().add(c);
c.setA(a);
c.setB(b);
ComplexPropertyPreFilter filter = new ComplexPropertyPreFilter();
filter.setExcludes(new HashMap<Class<?>, String[]>() {
private static final long serialVersionUID = -8411128674046835592L;
{
put(A.class, new String[] { "aid" });
put(B.class, new String[] { "bid", "a" });
put(C.class, new String[] { "a", "b" });
}
});
System.out.println(JSON.toJSONString(a, filter));
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
} public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public List<C> getC() {
return c;
}
public void setC(List<C> c) {
this.c = c;
}
}
import java.util.ArrayList;
import java.util.List;
public class B {
private Integer bid;
private A a;
private List<C> c = new ArrayList<>();
public B() {
super();
}
public Integer getBid() {
return bid;
}
public void setBid(Integer bid) {
this.bid = bid;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public List<C> getC() {
return c;
}
public void setC(List<C> c) {
this.c = c;
}
}
public class C {
private Integer id;
private A a;
private B b;
public C() {
super();
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
ok,代碼已貼好,測試方法在A類。