views:

2616

answers:

12

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.

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?

(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)

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.

+3  A: 

java.sql.Date extends 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.

cagcowboy
A: 

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.

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.

Shimi Bandiel
A: 

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.

andreasmk2
+5  A: 

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.

entzik
-1 - the long value is GMT, it does not require timezones.
Michael Borgwardt
A: 

You could use an encoder and decode to serialise and deserialise your objects.

Here is an example which serialises the SWT Rectangle class:

XMLEncoder encoder = new XMLEncoder(new FileOutputStream(file));
encoder.setPersistenceDelegate(
    Rectangle.class, 
    new DefaultPersistenceDelegate(new String[]{"x", "y", "width", "height"}));
encoder.writeObject(groups);
encoder.close();
paul
A: 

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.

boutta
+6  A: 

The date class has a clunky API. A better implementation is Joda Time. It also allows you to convert your date in a ISO8601 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)

JeroenWyseur
Alex Miller
Thanks! Didn't know that myself. Finally a better Date implementation.
JeroenWyseur
Nice article about the new API:http://today.java.net/pub/a/today/2008/09/18/jsr-310-new-java-date-time-api.html
JeroenWyseur
+3  A: 

To answer the first part of your question, I would suggest a string in iso 8601 format (this is a standard for encoding dates).

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.

Chris Gow
A: 

java.sql.Date already implements Serializable so no need to implement it :-)

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.

Yiannis
A: 

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.

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.

So I think the simplest way to get to java.sql.Date is to do a

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".

Argelbargel
+1  A: 

one caveat with java.sql.Date that bit me recently is that it doesn't store the time portions (hours, minutes, seconds, etc) just the date portion. if you want the full timestamp you have to use java.util.Date or java.sql.Timestamp

Matt
A: 

I have a similar issue. I have to serialize and deserialize java.util.Date objects but default java serialization takes too much time. XML is not being used instead each type of object to be serialized (there are not many types but many objects) is converted to its primitive form (e.g. Integer is stored as int, Boolean as boolean)

What is the best way to serialize Date using this strategy? Serialized data is always stored in a file and reader/writer are the same application, performance is a critical feature here