在 Java 中序列化日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/114575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Serializing Date in Java
提问by Slartibartfast
I'm passing around some objects through web service and some of them contain java.sql.Date. Because Date doesn't have empty constructor it doesn't want to get serialized.
我通过 Web 服务传递一些对象,其中一些包含 java.sql.Date。因为 Date 没有空的构造函数,所以它不想被序列化。
First part of a question is easy: what is the best way to pass a date between client and service?
问题的第一部分很简单:在客户端和服务之间传递日期的最佳方式是什么?
Second part is bit trickier: Once I decide how to pass dates around, I can obviously declare date transient and make some wrapper class to pass dates as String or whatever, but how to apply same solution as transparently as possible to several classes that include Date?
第二部分有点棘手:一旦我决定如何传递日期,我显然可以声明日期是瞬态的,并使一些包装类将日期作为字符串或其他形式传递,但是如何尽可能透明地将相同的解决方案应用于包含 Date 的几个类?
(I have a hunch that DynamicProxy thingy might be a solution, but reading documentation on Sun's site wasn't very helpful, so if it really is something in that direction, some clarification would be appreciated)
(我有一种预感,DynamicProxy thingy 可能是一个解决方案,但阅读 Sun 网站上的文档并不是很有帮助,所以如果它真的是朝这个方向发展的,我们将不胜感激)
Edit: I asked wrong question, sorry (some misunderstanding between me and coworker what is actually a problem). Problem occurs because of deserializing. So once I have date in xml format it tries to deserialize itself as GregorianCalendar. Other part of a question still remains: What is the best way to receive something (long timestamp or GregorianCalendar) and convert it to sql date, without making 10 different wrappers for 10 different classes. I'm using a NetBeans for code and wsdl generation.
编辑:我问错了问题,抱歉(我和同事之间有些误解实际上是什么问题)。由于反序列化而出现问题。所以一旦我有 xml 格式的日期,它就会尝试将自己反序列化为 GregorianCalendar。问题的其他部分仍然存在:接收某些东西(长时间戳或 GregorianCalendar)并将其转换为 sql 日期的最佳方式是什么,而不需要为 10 个不同的类制作 10 个不同的包装器。我使用 NetBeans 生成代码和 wsdl。
回答by cagcowboy
java.sql.Date extends java.util.Date
java.sql.Date 扩展 java.util.Date
Just use getTime() to get the long value from it. This can be serialized and a new java.sql.Date(long) or new java.util.Date(long) constructed from it at the other end.
只需使用 getTime() 从中获取 long 值。这可以被序列化,并在另一端从它构造一个新的 java.sql.Date(long) 或新的 java.util.Date(long) 。
回答by Shimi Bandiel
First, if you are using web services, it means you are serializing to XML and not your regular Java serialization (but some other library for marshaling and unmarshaling). So the question is lacking some information.
首先,如果您使用的是 Web 服务,这意味着您将序列化为 XML,而不是常规的 Java 序列化(而是一些其他用于编组和解组的库)。所以这个问题缺乏一些信息。
Second, if you have control over your InputStream & OutputStream try extending ObjectOutputStream and ObjectInputStream and override replaceObject()and resolveObject()and then you can implement serialization for java.sql.Date.
其次,如果您可以控制 InputStream 和 OutputStream,请尝试扩展 ObjectOutputStream 和 ObjectInputStream 并覆盖replaceObject()和resolveObject(),然后您可以实现 java.sql.Date 的序列化。
回答by Andreas Bakurov
You don't need default constructor (empty) in order to serialize/deserialize date (either java.sql.Date or java.util.Date). During deserialization constructor is not called but attributes of object set directly to values from serialized data and you can use the object as it is since it deserialized.
您不需要默认构造函数(空)来序列化/反序列化日期(java.sql.Date 或 java.util.Date)。在反序列化期间,不会调用构造函数,而是将对象的属性直接设置为来自序列化数据的值,您可以按原样使用该对象,因为它已反序列化。
回答by entzik
Serializing the long returned by Date.getTime() as previously suggested will work. You should however note that if your server is in another time zone than the client, the date you'll reconstruct on the other side will be different. If you want want to reconstruct exact same date object you also need to send your time zone (TimeZone.getID()) and use it to reconstruct the date on the other side.
按照之前的建议序列化 Date.getTime() 返回的 long 将起作用。但是,您应该注意,如果您的服务器位于与客户端不同的时区,则您将在另一端重建的日期将有所不同。如果您想重建完全相同的日期对象,您还需要发送您的时区 (TimeZone.getID()) 并使用它来重建另一侧的日期。
回答by paul
You could use an encoder and decode to serialise and deserialise your objects.
您可以使用编码器和解码器来序列化和反序列化您的对象。
Here is an example which serialises the SWT Rectangle class:
这是一个序列化 SWT Rectangle 类的示例:
XMLEncoder encoder = new XMLEncoder(new FileOutputStream(file));
encoder.setPersistenceDelegate(
Rectangle.class,
new DefaultPersistenceDelegate(new String[]{"x", "y", "width", "height"}));
encoder.writeObject(groups);
encoder.close();
回答by boutta
I've looked into the implementation of java.sql.Date and as I see it java.sql.Date is Serializable as an extension of java.util.Date.
我研究了 java.sql.Date 的实现,正如我所见,java.sql.Date 是可序列化的,作为 java.util.Date 的扩展。
回答by Jeroen Wyseur
Joda-Time
乔达时间
The Date class has a clunky API. A better implementation is Joda-Time.
Date 类有一个笨拙的 API。更好的实现是Joda-Time。
ISO 8601
ISO 8601
Joda-Time also allows you to convert your date in a ISO 8601standard format (yyyy-mm-ddTHH:MM:SS.SSS). Using this standard when moving dates from server to its client has the advantage to include the full date in a readable format. When you use for example JAXB, the XML representation of a date is also this ISO standard. (see the XMLGregorianCalendar class)
Joda-Time 还允许您将日期转换为ISO 8601标准格式 (yyyy-mm-ddTHH:MM:SS.SSS)。在将日期从服务器移动到其客户端时使用此标准具有以可读格式包含完整日期的优势。例如,当您使用JAXB 时,日期的 XML 表示也是此 ISO 标准。(请参阅 XMLGregorianCalendar 类)
回答by Chris Gow
To answer the first part of your question, I would suggest a string in iso 8601 format (this is a standard for encoding dates).
要回答您问题的第一部分,我建议使用 iso 8601 格式的字符串(这是编码日期的标准)。
For the second part, I'm not sure why you would need a proxy class? Or why you would have to extend the date class to support this. eg. would not your web service know that a certain field is a date and do the conversion from date to string and back itself? I'd need a little more information.
对于第二部分,我不确定为什么需要代理类?或者为什么你必须扩展日期类来支持这一点。例如。您的 Web 服务不会知道某个字段是日期并执行从日期到字符串的转换并返回自身吗?我需要更多信息。
回答by Ioannis
java.sql.Date already implements Serializable so no need to implement it :-)
java.sql.Date 已经实现了 Serializable 所以不需要实现它:-)
As far as your main question is concerned, I'm deeply in love with JAXB as I can turn almost any XML into an object, so it might be worth your while to look into it.
就您的主要问题而言,我非常喜欢 JAXB,因为我几乎可以将任何 XML 转换为对象,因此可能值得您花时间研究它。
回答by Argelbargel
Hmmm... Can't think of any reason why any serialized object-instance (serialized via the default java mechanism) should deserialize itself as an instance of another class as the class information should be an inherent part of the serialized data.
嗯...想不出任何原因为什么任何序列化的对象实例(通过默认的 java 机制序列化)应该将自身反序列化为另一个类的实例,因为类信息应该是序列化数据的固有部分。
So it's either a problem of your (de-)serialization framework or the framework accepts any "date-like" object on the "sending end" (Calendar, java.util.Date etc. - an thus java.sql.Date too as it extends java.util.Date), "serializes" it to a String in some common date-format (so the type information is lost) and "deserializes" it back to a Calendar object on the receiving end.
因此,这要么是您的(反)序列化框架的问题,要么是该框架在“发送端”(日历、java.util.Date 等)接受任何“类似日期”的对象 - 因此也是 java.sql.Date它扩展了 java.util.Date),将其“序列化”为某种常见日期格式的字符串(因此类型信息丢失),并将其“反序列化”为接收端的日历对象。
So I think the simplest way to get to java.sql.Date is to do a
所以我认为获取 java.sql.Date 的最简单方法是做一个
java.sql.Date date = new java.sql.Date(calendar.getTimeInMillis);
where you need an java.sql.Date but get the GregorianCalendar back from the "deserialization".
您需要一个 java.sql.Date 但从“反序列化”中获取 GregorianCalendar 的地方。