日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

浅析若干Java序列化工具

發(fā)布時間:2024/4/13 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析若干Java序列化工具 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
在java中socket傳輸數(shù)據(jù)時,數(shù)據(jù)類型往往比較難選擇。可能要考慮帶寬、跨語言、版本的兼容等問題。 比較常見的做法有:1. 采用java對象的序列化和反序列化2. 把對象包裝成JSON字符串傳輸3. Google工具protoBuf的開源對UserVo對象進行序列化,class UserVo如下: package com.serialize;import java.io.Serializable; import java.util.List;public class UserVo implements Serializable {private static final long serialVersionUID = -8647002929026226508L;private String name;private int age;private List<UserVo> friends;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public List<UserVo> getFriends() {return friends;}public void setFriends(List<UserVo> friends) {this.friends = friends;}@Overridepublic String toString() {return "UserVo [name=" + name + ", age=" + age + ", friends=" + friends + "]";}} package com.serialize;import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List;public class MainTest {public static void main(String[] args) throws IOException {UserVo user = new UserVo();user.setName("zzh");user.setAge(18);UserVo f1 = new UserVo();f1.setName("jj");f1.setAge(17);UserVo f2 = new UserVo();f2.setName("qq");f2.setAge(19);List<UserVo> friends = new ArrayList<UserVo>();friends.add(f1);friends.add(f2);user.setFriends(friends);ByteArrayOutputStream os = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(os);oos.writeObject(user);oos.flush();oos.close();System.out.println(os.toByteArray().length);}} 序列化大小:200優(yōu)點:java原生支持,不需要提供第三方的類庫,使用比較簡單。缺點:無法跨語言,字節(jié)數(shù)占用比較大,某些情況下對于對象屬性的變化比較敏感。 ##把對象包裝成JSON字符串傳輸JSON工具類有許多種,這里列出三個比較流行的json工具類:Jackson,Gson,FastJson.###1.開源的JacksonJackson社區(qū)相對比較活躍,更新速度也比較快。Jackson對于復雜類型的json轉(zhuǎn)換bean會出現(xiàn)問題,一些集合Map,List的轉(zhuǎn)換出現(xiàn)問題。Jackson對于復雜類型的bean轉(zhuǎn)換Json,轉(zhuǎn)換的json格式不是標準的Json格式。 package com.test.serialize;import java.io.IOException; import java.util.ArrayList; import java.util.List;import org.junit.After; import org.junit.Before; import org.junit.Test;import com.aztech.test.serialize.UserVo; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper;public class JacksonTest {private UserVo user = null;private JsonGenerator jsonGenerator;private ObjectMapper objectMapper = null;@Beforepublic void init() {user = new UserVo();user.setName("zzh");user.setAge(18);UserVo f1 = new UserVo();f1.setName("jj");f1.setAge(17);UserVo f2 = new UserVo();f2.setName("qq");f2.setAge(19);List<UserVo> friends = new ArrayList<UserVo>();friends.add(f1);friends.add(f2);user.setFriends(friends);objectMapper = new ObjectMapper();try {jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(System.out,JsonEncoding.UTF8);} catch (IOException e) {e.printStackTrace();}}@Afterpublic void destory() {try {if(jsonGenerator!=null) {jsonGenerator.flush();}if(!jsonGenerator.isClosed()) {jsonGenerator.close();}jsonGenerator = null;objectMapper = null;user = null;} catch (Exception e) {e.printStackTrace();}}@Testpublic void writeJson() {try {jsonGenerator.writeObject(user);System.out.println();System.out.println(objectMapper.writeValueAsBytes(user).length);} catch (IOException e) {e.printStackTrace();}}@Testpublic void readJson() {String serString = "{\"name\":\"zzh\",\"age\":18,\"friends\":[{\"name\":\"jj\",\"age\":17,\"friends\":null},{\"name\":\"qq\",\"age\":19,\"friends\":null}]}";UserVo userVo = null;try {userVo = objectMapper.readValue(serString, UserVo.class);} catch (IOException e) {e.printStackTrace();}System.out.println(userVo.getName()); } } {"name":"zzh","age":18,"friends":[{"name":"jj","age":17,"friends":null}, {"name":"qq","age":19,"friends":null}]} 111 序列化大小:111.注意到這里Jackson會輸出null,在Jackson的2.x版本中可以通過設置而使其不輸出null的字段。 ###2. Google的GsonGson是目前功能最全的Json解析神器,Gson當初是為因應Google公司內(nèi)部需求而由Google自行研發(fā)而來,但自從在2008年五月公開發(fā)布第一版后已被許多公司或用戶應用。Gson的應用主要為toJson與fromJson兩個轉(zhuǎn)換函數(shù),無依賴,不需要例外額外的jar,能夠直接跑在JDK上。而在使用這種對象轉(zhuǎn)換之前需先創(chuàng)建好對象的類型以及其成員才能成功的將JSON字符串成功轉(zhuǎn)換成相對應的對象。類里面只要有get和set方法,Gson完全可以將復雜類型的json到bean或bean到json的轉(zhuǎn)換,是JSON解析的神器。Gson在功能上面無可挑剔,但是性能上面比FastJson有所差距。 package com.aztech.test.serialize;import java.util.ArrayList; import java.util.List;import org.junit.Before; import org.junit.Test;import com.google.gson.Gson; import com.google.gson.JsonSyntaxException;public class GsonTest {private UserVo user = null;@Beforepublic void init() {user = new UserVo();user.setName("zzh");user.setAge(18);UserVo f1 = new UserVo();f1.setName("jj");f1.setAge(17);UserVo f2 = new UserVo();f2.setName("qq");f2.setAge(19);List<UserVo> friends = new ArrayList<UserVo>();friends.add(f1);friends.add(f2);user.setFriends(friends); }@Testpublic void writeJson() {try {String str = Gson.class.newInstance().toJson(user);System.out.println(str);System.out.println(str.length());} catch (InstantiationException | IllegalAccessException e) {e.printStackTrace();} }@Testpublic void readJson() {String serString = "{\"name\":\"zzh\",\"age\":18,\"friends\":[{\"name\":\"jj\",\"age\":17},{\"name\":\"qq\",\"age\":19}]}";try {UserVo userVo = Gson.class.newInstance().fromJson(serString, UserVo.class);System.out.println(userVo.getName());} catch (JsonSyntaxException | InstantiationException | IllegalAccessException e) {e.printStackTrace();}} } {"name":"zzh","age":18,"friends":[{"name":"jj","age":17},{"name":"qq","age":19}]} 81 Gson和Jackson的區(qū)別是:如果你的應用經(jīng)常會處理大的JSON文件,那么Jackson應該是你的菜。GSON在大文件上表現(xiàn)得相當吃力。如果你主要是處理小文件請求,比如某個微服務或者分布式架構(gòu)的初始化,那么GSON當是首選。Jackson在小文件上的表現(xiàn)則不如人意。 ###3. 阿里巴巴的FastJsonFastjson是一個Java語言編寫的高性能的JSON處理器,由阿里巴巴公司開發(fā)。無依賴,不需要例外額外的jar,能 夠直接跑在JDK上。 FastJson在復雜類型的Bean轉(zhuǎn)換Json上會出現(xiàn)一些問題,可能會出現(xiàn)引用的類型,導致Json轉(zhuǎn)換出錯,需要制定 引用。FastJson采用獨創(chuàng)的算法,將parse的速度提升到極致,超過所有json庫。 package com.aztech.test.serialize;import java.util.ArrayList; import java.util.List;import org.junit.Before; import org.junit.Test;import com.alibaba.fastjson.JSON;public class FastJsonTest {private UserVo user = null;@Beforepublic void init() {user = new UserVo();user.setName("zzh");user.setAge(18);UserVo f1 = new UserVo();f1.setName("jj");f1.setAge(17);UserVo f2 = new UserVo();f2.setName("qq");f2.setAge(19);List<UserVo> friends = new ArrayList<UserVo>();friends.add(f1);friends.add(f2);user.setFriends(friends); }@Testpublic void writeJson() {String str = JSON.toJSONString(user);System.out.println(str);System.out.println(str.length());}@Testpublic void readJson() {String serString = "{\"name\":\"zzh\",\"age\":18,\"friends\":[{\"name\":\"jj\",\"age\":17},{\"name\":\"qq\",\"age\":19}]}";UserVo userVo = JSON.parseObject(serString,UserVo.class);System.out.println(userVo.getName());} } {"age":18,"friends":[{"age":17,"name":"jj"},{"age":19,"name":"qq"}],"name":"zzh"} 81zzh 注:如果只是功能要求,沒有性能要求,可以使用google的Gson,如果有性能上面的要求可以使用Gson將bean轉(zhuǎn)換json確保數(shù)據(jù)的正確,使用FastJson將Json轉(zhuǎn)換Bean。 ##Google工具protoBufprotocol buffers 是google內(nèi)部得一種傳輸協(xié)議,目前項目已經(jīng)開源。它定義了一種緊湊得可擴展得二進制協(xié)議格式,適合網(wǎng)絡傳輸,并且針對多個語言有不同得版本可供選擇。protoBuf優(yōu)點:1. 性能好,效率高;2. 代碼生成機制,數(shù)據(jù)解析類自動生成;3. 支持向前兼容和向后兼容;4. 支持多種編程語言;5. 字節(jié)數(shù)很小,適合網(wǎng)絡傳輸節(jié)省io。缺點:1.應用不夠廣;2.二進制格式導致可讀性差;3.缺乏自描述;protoBuf是需要編譯工具的,這里用的是window的系統(tǒng)。需要下載proto.exe和protobuf-java-2.4.1.jar; 注:protobuf的一個缺點是需要數(shù)據(jù)結(jié)構(gòu)的預編譯過程,首先要編寫.proto格式的配置文件,再通過protobuf提供的工具生成各種語言響應的代碼。由于java具有反射和動態(tài)代碼生成的能力,這個預編譯過程不是必須的,可以在代碼執(zhí)行時來實現(xiàn)。protostuff(http://code.google.com/p/protostuff/)已經(jīng)實現(xiàn)了這個功能。protostuff基于Google protobuf,但是提供了更多的功能和更簡易的用法。其中,protostuff-runtime實現(xiàn)了無需預編譯對java bean進行protobuf序列化/反序列化的能力。protostuff-runtime的局限是序列化前需預先傳入schema,反序列化不負責對象的創(chuàng)建只負責復制,因而必須提供默認構(gòu)造函數(shù)。此外,protostuff還可以按照protobuf的配置序列化成json/yaml/xml等格式。這里不做詳述,有興趣的朋友可以參考相關資料。

?

方式優(yōu)點缺點
JSON
跨語言、格式清晰一目了然
字節(jié)數(shù)比較大,需要第三方類庫
Object Serializejava原生方法不依賴外部類庫字節(jié)數(shù)大,不能跨語言
Google protobuf跨語言、字節(jié)數(shù)比較少編寫.proto配置用protoc工具生成對應的代碼

?

總結(jié)

以上是生活随笔為你收集整理的浅析若干Java序列化工具的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。