有人知道java.util.Date是如何序列化的吗?我的意思是,给我解释一下每个字节到底是什么?我试着写出一个很长的日期,然后我可以看到匹配,但还有其他字符,我就是不明白。
我们的应用程序使用数据发出服务器请求,这意味着它会从客户机串行化到服务器。执行压力测试的团队使用一个工具来捕获这些请求并修改它们,问题是他们想要处理日期,而我不知道如何解释字节流。与我交谈的那个家伙似乎愿意学习,但到目前为止,我还没有找到任何我能理解的东西来指引他……
我使用的代码:
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try
{
fos = new FileOutputStream("t.tmp");
oos = new ObjectOutputStream(fos);
Date today = new Date();
oos.writeLong(today.getTime());
oos.writeObject("Today");
oos.writeObject(today);
oos.close();
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}编辑:
上面的输出是:
"¬í w ,áqÇ-t Todaysr java.util.DatehjKYt xpw ,áqÇ-x"长整型是"w,áq-“,那么长整型和Date对象之间的关系是什么,即"hjKYt xp”
注意一些空格是不能打印的字符NULL,SOH,backspace等等。我知道十六进制值才是最重要的。
编辑:
仍然有问题。出于某些原因,序列化的HTTP请求不会像我接受的答案那样序列化日期。非常接近,但仍然不同,我不知道为什么。更奇怪的是,当我简单地序列化一个日期时,它似乎工作得很好。仅供参考,在worj我们使用Websphere 6.1以下是请求中发送内容的一些示例:
lr_start_transaction("20000101");
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10\\x0BXxt\\x00\\x08
lr_start_transaction("20000102");
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10>\\x9Dxt\\x00\\x08
lr_start_transaction("20000103");
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10z\\xDBxt\\x00\\x08我已经能够识别大多数字段,但不能识别实际时间!例如,serialVersionUID为hj\\x81\\x01KYt\\x19
编辑(最终):
我找到了日期,但离我预期的还差得远呢!在我得到样本之后很久,因为出现了其他数据字段,我以为日期已经完成了--我只是碰巧注意到了我正在寻找的日期的十六进制模式!示例:
lr_start_transaction("20000101");
\\x0Ejava.util.Datehj\\x81\\x01KYt\\x19\\x03\\x00\\x00xpw\\x08\\x00\\x00\\x01,\\xE10\\x0BXxt\\x00\\x08OTTST153t\\x00\\x06/Web2/t\\x00\\x044971t\\x00\\x0B12ce12f737d\\x00\\x00\\x01,\\xE10\\x0BXsq\\x00~\\x00\\x0Fw\\x08\\x00\\x00\\x00\\xDCk\\xE2T\\x80xt日期值就在最后!
发布于 2010-12-14 04:39:20
/**
* Save the state of this object to a stream (i.e., serialize it).
*
* @serialData The value returned by <code>getTime()</code>
* is emitted (long). This represents the offset from
* January 1, 1970, 00:00:00 GMT in milliseconds.
*/
private void writeObject(ObjectOutputStream s)
throws IOException
{
s.writeLong(getTimeImpl());
}因此,它是长值,表示从Jan 1 1970 00:00:00 GMT开始的偏移量(以毫秒为单位)。
编辑:然而,这之前和之后有一些标题:
0x73 - being the code for an ordinary object (TC_OBJECT)
0x72 - being the code for a class description (TC_CLASSDESC)
"java.util.Date" - the name of the class
7523967970034938905L - the serialVersionUID
0|0x02|0x01 - flags including SC_SERIALIZABLE & SC_WRITE_METHOD
0 - number of fields
0x78 - TC_ENDBLOCKDATA
null - there is no superclass descriptor
the time (long milliseconds since epoch)
0x78 - TC_ENDBLOCKDATA发布于 2010-12-14 04:42:26
Java对象序列化格式的细节在Java Object Serialization Specification中指定。除了魔术和版本号之外,Date类的细节和对象是Date的事实都被写入到流中。
API doc for Date serialised form为:
发出getTime()返回的值(
)。这表示从1970年1月1日00:00:00 GMT开始的偏移量,以毫秒为单位。
请注意,它实际上违反了规范,因为它没有调用defaultWriteObject或putFields。
https://stackoverflow.com/questions/4433198
复制相似问题