Hi Bjorn Bjorn Roche wrote:
> Hey all, > > First off, I heart XStream. I just wanted to share a problem I had > recently and how I solved it. It seems to me the solution is unintuitive > and hard to find. This maybe isn't a bug, but at the very least I think it > should be easier to do what I needed to do, or maybe his needs to be a FAQ > or something. > > So here's my story: > > I noticed my dates were not being converted the way I wanted. After much > searching I found this: http://jira.codehaus.org/browse/XSTR-116 Ah hah! > that's all I need to do! > > - first comment: that should be a FAQ or something. ISO8601 dates are > pretty widely accepted as standard for XML, right? If they don't work > automatically, it should be easy for people to figure out how to make them > work, and I think the FAQ is the right place for that. The ISO8601 converters are listed: http://xstream.codehaus.org/converters.html > So I installed Jodatime, registered my converter and thought I was done > with it. But I wasn't. Unbeknownst to me, my persistence engine was > converting my java.util.date objects to java.sql.timestamp objects.... > sometimes. One solution, of course, was to manually change that, since I > was using different objects for persistence and XML conversion, but that > seemed error-prone. Not a good solution. SO I thought the right was would > be to make XStream handle this. > > The problem was here: > > public class ISO8601DateConverter extends > ISO8601GregorianCalendarConverter { > > public boolean canConvert(Class type) { > return type.equals(Date.class); > } > ... > } > > The date converter was only handling java.util.Date classes and not > subclasses. Was that intentional? I don't know, but my solution was to do > this: > > public static ISO8601DateConverter DATE_CONVERTER = new > ISO8601DateConverter() { @Override > public boolean canConvert(Class type) { > return Date.class.isAssignableFrom(type); > } > }; > > That worked! horray! Now java.util.Date AND ALL SUBCLASSES are converted > to ISO8601 dates, like I wanted. > > - Second Comment/question: Is this a bug, or was that intentional? Intentional. How can XStream know what additional fields/data a derived class might have? The ISO8601DateConverter will never produce a different string representation. > If it > was intentional, is my subclassed cade safe? No. > Now here's the problem I don't really understand: the timestamp objects > still converted like this: > > <cTime class="sql-timestamp">2012-03-17T20:44:00.490Z</cTime> > > So the date/time format is right, but the class annotation confuses > XStream when trying to deserialize this. No, it is simply ignored, because the ISO8601DateConverter only creates Date instances. And XStream will throw an exception afterwards, since it expected the converter to produce a Timestamp. > The solution, which was > counterintuitive to me, was this: > > XStream xstream = super.createXstream(mediaType); > xstream.addDefaultImplementation(java.sql.Date.class,java.util.Date.class); > xstream.addDefaultImplementation(java.sql.Timestamp.class,java.util.Date.class); > xstream.addDefaultImplementation(java.sql.Time.class,java.util.Date.class); > xstream.registerConverter(DATE_CONVERTER); > > That gets rid of the pesky annotation, although I suppose some other > subclass could come along and mess things up. You simply suppressed the check of XStream. You still create only Date instances. XStream will no longer care if your data structures (and your application afterwards) expect something else. ClassCastExceptions are to be expected. > - Third comment/question: Is this the best way? Am I missing something? If > this is the best way, I think there should be a better way as this is > unintuitive and potentially error prone if another date subclass comes > along. Registering the ISO8601SqlTimestampConverter? Cheers, Jörg --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email
