本文目錄一覽:
- 1、Android json解析架包(阿里巴巴的fastjson)處理是報異常。
- 2、複雜json怎麼使用fastjson一次性提取出來
- 3、Jackson和FastJson性能誰更快
- 4、java-fastJson:請問下面代碼有什麼錯?為什麼打印出來後numString始終為空呢?
- 5、Fastjson 1.83漏洞利用猜想
- 6、fastjson是怎麼實現JSON的序列化和反序列化的
Android json解析架包(阿里巴巴的fastjson)處理是報異常。
應該是json字符串的格式有問題吧,先找找看有問題沒有,沒有的話再看解析的時候哪裡有邏輯問題沒有,不行就把報錯的那幾行代碼和json字符串貼出來,幫你看看能不能找到哪裡有問題
複雜json怎麼使用fastjson一次性提取出來
JSON數據之使用Fastjson進行解析(一)
據說FastJson是目前最快的解析Json數據的庫,而且是國人開發出來的開源庫。頂一下,付上官方網址:h/code.alibabatech.com/wiki/pages/viewpage.action?pageId=2424946
要使用Fastjson,首先需要下載相對應的jar文件,在官網即可下載。
附上初學的第一個例子,多多指教:
複製代碼
{
“statuses”:[
{
“id”: 912345678901,
“text”: “How do I stream JSON in Java?”,
“geo”: null,
“user”: {
“name”: “json_newb”,
“followers_count”: 41
}
},
{
“id”: 777777777888,
“text”: “dfngsdnglnsldfnsl”,
“geo”: null,
“user”: {
“name”: “dsfgpd”,
“followers_count”: 24
}
}
]
}
複製代碼
AllBean的Bean類:
複製代碼
package com.lee.JsonToBean;
public class AllBean {
private long id;
private String text;
private String geo;
private UserBean userBean;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getGeo() {
return geo;
}
public void setGeo(String geo) {
this.geo = geo;
}
public UserBean getUserBean() {
return userBean;
}
public void setUserBean(UserBean userBean) {
this.userBean = userBean;
}
}
複製代碼
UserBean的Bean類:
複製代碼
package com.lee.JsonToBean;
public class UserBean {
private String name;
private int followers_count;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getFollowers_count() {
return followers_count;
}
public void setFollowers_count(int followers_count) {
this.followers_count = followers_count;
}
}
複製代碼
解析類JsonBean:
複製代碼
package com.lee.JsonToBean;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.rtf.RTFEditorKit;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/**
* {
“statuses”:[
{
“id”: 912345678901,
“text”: “How do I stream JSON in Java?”,
“geo”: null,
“user”: {
“name”: “json_newb”,
“followers_count”: 41
}
},
{
“id”: 777777777888,
“text”: “dfngsdnglnsldfnsl”,
“geo”: null,
“user”: {
“name”: “dsfgpd”,
“followers_count”: 24
}
}
]
}
* */
public class JsonBean {
RTFEditorKit rtf;
DefaultStyledDocument dsd;
String text;
public static void main(String[] args) {
JsonBean bean = new JsonBean();
// 把字符串轉為Json對象,這是因為我的json數據首先是json對象
JSONObject jobj = JSON.parseObject(bean.readRtf(new File(“json.rtf”)));
// 然後是jsonArray,可以根據我的json數據知道
JSONArray arr = jobj.getJSONArray(“statuses”);
// 根據Bean類的到每一個json數組的項
ListAllBean listBeans = JSON.parseArray(arr.toString(), AllBean.class);
// 遍歷
for(AllBean bean_ : listBeans){
// 我這個demo的json數據獲得第一層的數據
System.out.println(bean_.getText());
System.out.println(bean_.getId());
// 我這個demo的json數據獲得第二層的數據
System.out.println(bean_.getUserBean().getFollowers_count());
}
}
// 因為我把json數據放進rtf文件,這是讀取rtf文件的json數據,轉化為字符串
public String readRtf(File in) {
rtf=new RTFEditorKit();
dsd=new DefaultStyledDocument();
try {
rtf.read(new FileInputStream(in), dsd, 0);
text = new String(dsd.getText(0, dsd.getLength()));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return text;
}
}
Jackson和FastJson性能誰更快
Fastjson快,但是和jackson 的差距不大,優勢並沒有太明顯。Jackson還可以加上AfterBurner來使用byte generation,這樣和Fastjson的差距就更小了。
除了速度勝出外,Fastjson相比較 Jackson 有不少短板。
1. 可定製性
Jackson有靈活的API,可以很容易進行擴展和定製,而且很多時候需要的模塊都已經有人提供了。比如guava中定義的數據類型,比如kotlin語言Immutable的類型等,比如java8 引入的新日期時間類型和Optional都已經有支持的模塊。
FastJson只有一個(簡陋)的SerializeFilter機制用來定製序列化,ParseProcess機制用來定製反序列化,每次調用序列化/反序列化的的時候都要自己傳filter或者Process這個參數過去,Jackson和 Gson都是直接註冊模塊就可以了,Jackson還可以使用SPI來自動發現和註冊模塊。
2. 代碼質量
公司有一些項目使用了fastjson,在使用fastjson的項目裡面碰到的兩個低級bug:
1. 碰到在128~255 的字符直接異常,這些主要是西歐語言的字符,因為他用一個數組來記錄 轉義後的字符表示,但是數組長度只有128…
2. 內存佔用過多。Fastjson為了性能,在ThreadLocal中緩存了char[] buffer,這樣避免分配內存和gc的開銷。但是如果碰到了大的json(比如10M這樣的),就會佔用大量的內存,而且以後都是處理小json了內存佔用也回不來。
這些問題雖然後來的版本都修復了,但是也反映出Fastjson代碼質量上要求不夠嚴格。 而Jackson這麼多年來使用上還沒有碰到過這樣的Bug.
3. 文檔
英文文檔缺乏已有的也不規範,相比較國內用戶還多些。
java-fastJson:請問下面代碼有什麼錯?為什麼打印出來後numString始終為空呢?
public class User{ //user類改成這樣,其他不用改
public int a=0;
public String b=””;
public boolean c=false;
User(){ }
}
Fastjson 1.83漏洞利用猜想
在不久前fastjson1.2.83又爆出來了新的問題,詳細內容可以參考 ,這篇文章主要是拋轉引玉,寫一種可能的利用思路,詳細的利用鏈可能要等大佬們來給出了。
文內如有不妥之處,還請批評指正。
特定依賴存在下影響 ≤1.2.80
首先看白名單對比:
這裡參考之前git上的白名單列表
像org.springframework中的基本全部從白名單中剔除了。
並且更改了判斷方式,if (typeName.endsWith(“Exception”) || typeName.endsWith(“Error”))
那麼這裡就可以猜測本次影響的方式,就是和被剔除的內容相關。這裡用org.springframework.dao.CannotAcquireLockException進行測試,可以發現實際上最終調用的類是Throwable。
那麼如果是要找gadget的話,就需要從黑名單下手了。本文不做分析和介紹,有興趣找gadget的話可以去研究研究。
需要使用1.2.80和1.2.83的fastjson jar包進行測試。
maven
demo:
上重點從checkAutoType開始,簡單的說一下判斷過程。
首先是判斷safeModeMask,通常默認是不會開的。
檢測黑名單
通過黑白名單的檢測,就會嘗試從Mapping中獲取類
走到這裡如果是白名單里的內容會嘗試進行加載。
並且會直接拿到對應的類,不會再進行接下來的校驗。
由於存在繼承調用關係,所以在進行加載的時候就會加載f1283,並且會重新進行checkAutoType的判定。
檢測過程中會先將expectClassFlag置為true。
接着檢測黑名單內容,Mapping獲取以及白名單檢測無果之後會對clazz的類型進行校驗。
接着會進行新一輪的檢測。
檢測通過之後,會進行類繼承關係判斷,實際上只要繼承關係正確,就會直接進行反序列化。
最後的結果
如果直接使用java.lang.Throwable會直接拋出異常。
我們來跟一下可以很清楚的看到,Throwable既不是黑名單,也不是白名單,也不是mapping中的內容。
那麼在流程中就會將這個類當做一個普通的類來進行處理,通過判斷autoTypeSupport為未開啟的狀態,從而進行拋出處理。
fastjson是怎麼實現JSON的序列化和反序列化的
GitHub – alibaba/fastjson: Fast JSON Processor
如果題主只是問序列化和反序列化部分,而不注重JSON的語法分析部分的話,fastjson的序列化和反序列化都是通過動態生成類來避免重複執行時的反射開銷的。
動態生成序列化器的類的代碼可以從這裡開始看:fastjson/ASMSerializerFactory.java at master · alibaba/fastjson · GitHub
動態生成反序列化器的類的代碼可以從這裡開始看:fastjson/DeserializerGen.java at master · alibaba/fastjson · GitHub
原創文章,作者:SZCX,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/148918.html