摘要:序列化對(duì)象要保留充分的信息,用來恢復(fù)數(shù)據(jù)對(duì)象,但是為了節(jié)約存儲(chǔ)空間和網(wǎng)絡(luò)帶寬,序列化出的二進(jìn)制流要盡可能小。序列化序列化是一種支持動(dòng)態(tài)類型跨語言基于對(duì)象傳輸?shù)木W(wǎng)絡(luò)協(xié)議,對(duì)象序列化后的二進(jìn)制流,可以被其他語言反序列化。
記得很久以前寫代碼的時(shí)候,每次新建一個(gè)實(shí)體都會(huì)下意識(shí)的繼承Serializable接口,大部分人都知道這是對(duì)對(duì)象的序列化,可是你們真的知道序列化嗎?這篇文章就簡(jiǎn)單的說下java中的序列化,讓你更多的理解java這門語言。
關(guān)于上篇文章說的,在應(yīng)用登錄前使用第三方的人機(jī)驗(yàn)證,如果第三方的產(chǎn)品突然出現(xiàn)故障,無法使用,這種狀況我們應(yīng)該怎么應(yīng)對(duì),在團(tuán)隊(duì)中我們也討論過這種情況,我們的方案就是客戶端不直接的請(qǐng)求第三方,而是由后端服務(wù)器充當(dāng)一個(gè)中介的角色,起轉(zhuǎn)發(fā)作用,這樣在第三方出現(xiàn)問題,我們服務(wù)器端會(huì)做處理,這也是不把雞蛋放在同一個(gè)籃子里的思想。
接下來,簡(jiǎn)單的說下序列化,
將數(shù)據(jù)對(duì)象轉(zhuǎn)換為二進(jìn)制流的過程就稱為對(duì)象的序列化(Serialization),反過來,將二進(jìn)制流轉(zhuǎn)換為對(duì)象就是反序列化(Deserializable)。序列化的用處是什么呢?共兩點(diǎn):
1、數(shù)據(jù)持久化:在很多應(yīng)用中,需要對(duì)好多對(duì)象進(jìn)行序列化,存到物理硬盤,較長(zhǎng)時(shí)間的保存,比如,Session對(duì)象,當(dāng)有數(shù)萬用戶并發(fā)訪問的時(shí)候,就會(huì)有數(shù)萬的Session對(duì)象,內(nèi)存會(huì)承受很大的壓力,這個(gè)時(shí)候,就會(huì)把一些對(duì)象先序列化到硬盤中,需要使用的時(shí)候再還原到內(nèi)存中。序列化對(duì)象要保留充分的信息,用來恢復(fù)數(shù)據(jù)對(duì)象,但是為了節(jié)約存儲(chǔ)空間和網(wǎng)絡(luò)帶寬,序列化出的二進(jìn)制流要盡可能小。
2、網(wǎng)絡(luò)傳輸:當(dāng)兩個(gè)進(jìn)程在互相通信的時(shí)候,就會(huì)進(jìn)行數(shù)據(jù)傳輸,不管是何種類型的數(shù)據(jù),都必須要轉(zhuǎn)成二進(jìn)制流來傳輸,接受方收到后再轉(zhuǎn)為數(shù)據(jù)對(duì)象。
重點(diǎn)來了,序列化在代碼中是怎么實(shí)現(xiàn)的呢?以下介紹三種:
1、java原生序列化:java類通過實(shí)現(xiàn)Serializable接口來實(shí)現(xiàn)。這個(gè)接口沒有任何方法,只是標(biāo)識(shí),java序列化保留了對(duì)象的元數(shù)據(jù),以及對(duì)象數(shù)據(jù),兼容性最好,但是不支持跨語言,性能也一般。
public class BaseEntity implements Serializable {
private static final long serialVersionUID = -7333816285916354999L; private Long id; public BaseEntity() { } public Long getId() { return this.id; } public void setId(Long id) { this.id = id; }
}
實(shí)現(xiàn)這個(gè)接口,idea會(huì)給你一個(gè)警告,它會(huì)建議你設(shè)置一個(gè)serialVersionUID,如果你不設(shè)置,編譯器會(huì)根據(jù)類的內(nèi)部實(shí)現(xiàn),包括類名、接口名、方法和屬性來自動(dòng)生成serialVersionUID 如果類的源碼有修改,重新編譯后這個(gè)值也會(huì)變化。
在修改類的時(shí)候,我們要根據(jù)兼容性來決定是否修改serialVersionUID,如果是兼容性質(zhì)的升級(jí),不建議修改,因?yàn)榭赡軙?huì)反序列化失敗。如果是不兼容的,就需要修改,避免反序列化變得混亂。
java原生序列化,在反序列化的時(shí)候不會(huì)調(diào)用類的無參構(gòu)造方法,而是調(diào)用native方法將屬性賦值為對(duì)應(yīng)類型的初始值。
最后,基于性能及兼容性,不推薦使用。
2、Hessian序列化:Hessian序列化是一種支持動(dòng)態(tài)類型、跨語言、基于對(duì)象傳輸?shù)木W(wǎng)絡(luò)協(xié)議,java對(duì)象序列化后的二進(jìn)制流,可以被其他語言反序列化。它的特性:
自描述序列化類型,不依賴外部描述文件或接口定義,用一個(gè)字節(jié)表示常用的基礎(chǔ)類型,極大縮短二進(jìn)制流;
語言無關(guān),支持腳本語言。
協(xié)議簡(jiǎn)單,比java原生的要高效。
需要注意一點(diǎn):Hessian會(huì)把復(fù)雜對(duì)象所有屬性存儲(chǔ)在一個(gè)Map中進(jìn)行序列化,所以在父類和子類含有相同字段的情況下,先序列化子類,后序列化父類,這樣的結(jié)果是子類的同名屬性會(huì)被父類覆蓋掉。
以下是代碼實(shí)現(xiàn)
/**
* Hessian實(shí)現(xiàn)序列化 * * @param TestClass * @return * @throws IOException */ private static byte[] serialize(TestClass TestClass) { ByteArrayOutputStream byteArrayOutputStream = null; HessianOutput hessianOutput = null; try { byteArrayOutputStream = new ByteArrayOutputStream(); // Hessian的序列化 hessianOutput = new HessianOutput(byteArrayOutputStream); hessianOutput.writeObject(TestClass); return byteArrayOutputStream.toByteArray(); } catch (IOException e) { e.printStackTrace(); } finally { try { byteArrayOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } try { hessianOutput.close(); } catch (IOException e) { e.printStackTrace(); } } return null; }
3、JSON序列化:
JSON是一種輕量級(jí)的數(shù)據(jù)交換格式,這種序列化方式就是講數(shù)據(jù)對(duì)象轉(zhuǎn)換為JSON字符串。在序列化的過程中舍棄了類型信息。反序列化是只有在提供了類型信息的情況下才能完成。
public staticT fromJson(String json, Class type) { if (json != null && !json.equals("")) { try { return getObjectMapper().readValue(json, type); } catch (Exception var3) { var3.printStackTrace(); return null; } } else { return null; } }
相信大部分讀者的公司和前端和客戶端數(shù)據(jù)的交互格式都是JSON吧,因?yàn)镴SON的這種格式可讀性較好,而且也方便調(diào)試。
序列化通常會(huì)用于網(wǎng)絡(luò)傳輸數(shù)據(jù)對(duì)象,而對(duì)象中常常會(huì)含有敏感數(shù)據(jù),所以黑客常常會(huì)攻擊這點(diǎn),攻擊手段通常是利用反序列化過程構(gòu)造惡意代碼,怎么應(yīng)對(duì)這種情況呢?可以使用transient關(guān)鍵字來修飾這個(gè)屬性,這樣在反序列化之后該屬性就會(huì)為空,如果一定要傳遞的話,可以使用對(duì)稱加密或非對(duì)稱加密獨(dú)立傳輸,在數(shù)據(jù)傳輸?shù)膯栴}上,我們一定要具備安全意識(shí)。
希望看完這篇文章的你能有所收獲。
分享以下自己的思考:”對(duì)于用戶來說,系統(tǒng)太靈活是他們的負(fù)擔(dān),意味著他們要做更多的選擇,對(duì)于技術(shù)人員來說,架構(gòu)靈活可以應(yīng)對(duì)更多的運(yùn)營(yíng)策略。怎樣折中,是個(gè)問題?!?/p>
這樣的分享我會(huì)一直持續(xù),你的關(guān)注、轉(zhuǎn)發(fā)和點(diǎn)贊是對(duì)我最大的支持,感謝。
題圖:作者實(shí)拍
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/74095.html
摘要:在反射方面來說,從運(yùn)行時(shí)返回一個(gè)的實(shí)例時(shí)不需要經(jīng)過強(qiáng)制轉(zhuǎn)換然后則需要經(jīng)過轉(zhuǎn)換才能得到。如果對(duì)數(shù)據(jù)的數(shù)量大小已知,操作也非常簡(jiǎn)單,也不需要中的大部分方法,也是可以直接使用數(shù)組的。 showImg(https://segmentfault.com/img/bVbruTp?w=1920&h=1080); 我在想每個(gè)人在面試的時(shí)候都會(huì)被問到集合相關(guān)的問題,有好大一部分人在回答的時(shí)候并沒有那么多...
摘要:到十二月份,公司開始第二波裁員,我決定主動(dòng)拿賠償走人。加一個(gè)小插曲上面的題是餓了嗎面試問到的。想去的公司沒有面試好,不要?dú)怵H,繼續(xù)加油準(zhǔn)備。避免打擊自信心。 回顧一下自己這段時(shí)間的經(jīng)歷,九月份的時(shí)候,公司通知了裁員,我匆匆忙忙地出去面了幾家,但最終都沒有拿到offer,我感覺今年的寒冬有點(diǎn)冷。到十二月份,公司開始第二波裁員,我決定主動(dòng)拿賠償走人。后續(xù)的面試過程我做了一些準(zhǔn)備,基本都能走...
摘要:面經(jīng)因?yàn)槲彝耆珱]有面試經(jīng)驗(yàn),從來沒有經(jīng)歷過面試,于是想著在去這類大公司面試之前先找成都的小公司練練手,積累點(diǎn)面試經(jīng)驗(yàn)。于是三月份開始就有成都的小公司開始約我面試。 前序 從我高考成績(jī)出來那一刻開始,從我在高考志愿上填上計(jì)算機(jī)科學(xué)與技術(shù)這幾個(gè)當(dāng)時(shí)在心中堪稱神圣的幾個(gè)字開始,我就已經(jīng)把進(jìn)入中國(guó)互聯(lián)網(wǎng)最高殿堂BAT作為我整個(gè)大學(xué)奮斗的目標(biāo),哪怕我就讀的是一所位于內(nèi)陸的雙非一本大學(xué)我也認(rèn)為我能...
前言 正逢金九銀十,有很多朋友已經(jīng)在考慮自己的出路了,今天給大家分享的是我一位幸運(yùn)拿到京東軟件測(cè)試offer的朋友的面試經(jīng)歷,我也閑來無事,問到了我朋友京東面試的一些真題,以及我整理的一些真題分享給大家,希望能夠幫助大家沖刺金九銀十,像我的朋友一樣拿到自己心儀的offer。 三面京東: 一面: 你所了解的黑盒測(cè)試方法有哪些?并簡(jiǎn)單介紹下其應(yīng)用場(chǎng)景?簡(jiǎn)述常用的bug管理或者用例管理工具,并且描述其...
閱讀 915·2021-11-12 10:36
閱讀 3496·2021-09-08 10:44
閱讀 2817·2019-08-30 11:08
閱讀 1481·2019-08-29 16:12
閱讀 2752·2019-08-29 12:24
閱讀 1007·2019-08-26 10:14
閱讀 778·2019-08-23 18:32
閱讀 1259·2019-08-23 17:52