Я передаю некоторые объекты через веб-службу, а некоторые из них содержат java.sql.Date. Поскольку у Date нет пустого конструктора, он не хочет сериализоваться.
Первая часть вопроса проста: как лучше всего провести свидание между клиентом и службой?
Вторая часть немного сложнее: как только я решу, как передавать даты, я, очевидно, могу объявить временную дату и сделать некоторый класс-оболочку для передачи дат как String или что-то еще, но как применить то же решение как можно более прозрачно к нескольким классам, которые включают Date ?
(У меня есть подозрение, что DynamicProxy может быть решением, но чтение документации на сайте Sun не очень помогло, поэтому, если это действительно что-то в этом направлении, некоторые пояснения были бы признательны)
Обновлено: я задал неправильный вопрос, извините (какое-то недоразумение между мной и коллегой, что на самом деле является проблемой). Проблема возникает из-за десериализации. Итак, как только у меня есть дата в формате xml, он пытается десериализовать себя как GregorianCalendar. Остается еще одна часть вопроса: как лучше всего получить что-либо (длинную временную метку или GregorianCalendar) и преобразовать это в дату sql, не создавая 10 разных оболочек для 10 разных классов. Я использую NetBeans для создания кода и wsdl.




java.sql.Date расширяет java.util.Date
Просто используйте getTime (), чтобы получить от него длинное значение. Это может быть сериализовано, и на другом конце из него может быть создан новый java.sql.Date (long) или новый java.util.Date (long).
Во-первых, если вы используете веб-службы, это означает, что вы сериализуете в XML, а не в обычную сериализацию Java (а в какую-то другую библиотеку для маршалинга и демаршалинга). Так что в вопросе не хватает информации.
Во-вторых, если у вас есть контроль над InputStream и OutputStream, попробуйте расширить ObjectOutputStream и ObjectInputStream и переопределить replaceObject () и resolveObject (), а затем вы можете реализовать сериализацию для java.sql.Date.
Вам не нужен конструктор по умолчанию (пустой) для сериализации / десериализации даты (либо java.sql.Date, либо java.util.Date). Во время десериализации конструктор не вызывается, но атрибуты объекта устанавливаются непосредственно на значения из сериализованных данных, и вы можете использовать объект как есть, поскольку он десериализован.
Сериализация long, возвращаемого Date.getTime (), как было предложено ранее, будет работать. Однако вы должны отметить, что если ваш сервер находится в другом часовом поясе, чем клиент, дата, которую вы реконструируете на другой стороне, будет другой. Если вы хотите восстановить точно такой же объект даты, вам также необходимо отправить свой часовой пояс (TimeZone.getID ()) и использовать его для восстановления даты на другой стороне.
если вы сериализуете 2 часа дня в Париже, вы получите 8 утра, если десериализуете тот же поток на машине, настроенной для часового пояса Нью-Йорка. Если вы хотите запланировать встречу, это нормально, потому что вы хотите, чтобы все присутствовали одновременно. Но если вам нужно отобразить информацию о контракте (например, этот параметр истекает в 14:00 в Париже), вам необходимо отправить часовой пояс, чтобы компьютер Нью-Йорка определил, что в Париже 14:00, а не 8:00, и, кстати,. Бизнес-модели существуют для обеих ситуаций, отправка по часовому поясу всегда безопасна, за исключением случаев, когда у вас есть строгие ограничения полосы пропускания.
Вы можете использовать кодировщик и декодировать для сериализации и десериализации ваших объектов.
Вот пример, который сериализует класс 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();
Я изучил реализацию java.sql.Date, и, как я вижу, java.sql.Date является сериализуемым как расширение java.util.Date.
Класс Date имеет неуклюжий API. Лучшая реализация - Джода-Тайм.
Joda-Time также позволяет преобразовывать дату в стандартный формат ISO 8601 (гггг-мм-ддTHH: MM: SS.SSS). Использование этого стандарта при переносе дат с сервера на его клиент имеет то преимущество, что включает полную дату в удобочитаемом формате. Когда вы используете, например, JAXB, XML-представление даты также является этим стандартом ISO. (см. класс XMLGregorianCalendar)
Также обратите внимание, что предстоящий JSR 310 Date & Time API для Java 7 будет основан на ISO8601 и концепциях от Joda Time. Так что это хорошее направление на будущее.
Спасибо! Сам не знал. Наконец, лучшая реализация Date.
Хорошая статья о новом API: today.java.net/pub/a/today/2008/09/18/…
Чтобы ответить на первую часть вашего вопроса, я бы предложил строку в формате iso 8601 (это стандарт кодирования дат).
Что касается второй части, я не уверен, зачем вам нужен прокси-класс? Или почему вам нужно было бы расширить класс даты для поддержки этого. например. разве ваша веб-служба не узнает, что определенное поле является датой, и не выполнит ли преобразование даты в строку и обратно? Мне нужно немного больше информации.
java.sql.Date уже реализует Serializable, поэтому нет необходимости его реализовывать :-)
Что касается вашего основного вопроса, я глубоко влюблен в JAXB, так как я могу превратить почти любой XML в объект, так что, возможно, стоит потратить время на его изучение.
Хммм ... Не могу придумать ни одной причины, по которой какой-либо сериализованный экземпляр объекта (сериализованный через механизм Java по умолчанию) должен десериализоваться как экземпляр другого класса, поскольку информация о классе должна быть неотъемлемой частью сериализованных данных.
Так что это либо проблема вашей (де-) сериализации, либо фреймворк принимает любой «похожий на дату» объект на «отправляющем конце» (Calendar, java.util.Date и т. д. - таким образом, java.sql.Date тоже как он расширяет java.util.Date), «сериализует» его в String в некотором общем формате даты (так что информация о типе теряется) и «десериализует» его обратно в объект Calendar на принимающей стороне.
Поэтому я думаю, что самый простой способ добраться до java.sql.Date - это сделать
java.sql.Date date = new java.sql.Date(calendar.getTimeInMillis);где вам нужен java.sql.Date, но вы получите GregorianCalendar обратно из "десериализации".
одно предостережение с java.sql.Date, которое меня недавно укусило, заключается в том, что он не хранит части времени (часы, минуты, секунды и т. д.), а только часть даты. если вам нужна полная временная метка, вы должны использовать java.util.Date или java.sql.Timestamp
Я буду расширять правильный ответ от JeroenWyseur.
Стандартный формат ISO 8601 - лучший способ сериализации значения даты и времени для обмена данными. Формат однозначный, интуитивно понятный для людей из разных культур и становится все более распространенным во всем мире. Легко читается как людьми, так и машинами.
2015-01-16T20:15:43+02:00
2015-01-16T18:15:43Z
В первом примере смещение опережает UTC на два часа. Во втором примере показано обычное использование Z («Zulu») для обозначения UTC, сокращение от +00:00.
Классы java.util.Date и .Calendar, связанные с Java, общеизвестно хлопотны, сбивают с толку и ошибочны. Избежать их. Вместо этого используйте:
Пакет java.time заменяет своего предшественника, библиотеку Джода-Тайм.
По умолчанию обе библиотеки используют ISO 8601 как для синтаксического анализа, так и для генерации строковых представлений значений даты и времени.
Обратите внимание, что java.time расширяет формат ISO 8601, добавляя собственное имя часового пояса, например 2007-12-03T10:15:30+01:00[Europe/Paris].
Найдите на StackOverflow.com сотни вопросов и ответов с подробным обсуждением и примерами кода.
В некоторых других ответах рекомендуется использовать число, количество от эпоха. Такой подход непрактичен. Это не самоочевидно. Он не читается человеком, поэтому отладка затруднительна и утомительна.
Какое это число: целые секунды, обычно используемые в Unix, миллисекунды, используемые в java.util.Date и Joda-Time, микросекунды, обычно используемые в базах данных, таких как Postgres, или наносекунды, используемые в пакет java.time?
Какой из пара десятков эпох, первый момент 1970 года, используемый в Unix, год 1, используемый в .Net & Go, «0 января 1900 года», используемый в миллионах (миллиардах?) Таблиц Excel и Lotus, или 1 января 2001 года, используемый Какао?

См. мой ответ по аналогичному вопросу для более подробного обсуждения.
LocalDateI'm passing around some objects through web service and some of them contain java.sql.Date
Замена ужасного класса java.sql.Date - java.time.LocalDate.
Лучше всего полностью избегать устаревшего класса, но вы можете конвертировать туда и обратно, вызывая новые методы, добавленные к старому классу: myJavaSqlDate.toLocalDate()
LocalDateКласс LocalDate реализует Serializable. Таким образом, у вас не должно возникнуть проблем с его автоматической сериализацией, как маршалингом, так и демаршалингом.
Фреймворк java.time встроен в Java 8 и новее. Эти классы заменяют неудобные старые классы даты и времени наследие, такие как java.util.Date, Calendar, & SimpleDateFormat.
Чтобы узнать больше, см. Учебник Oracle. И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310.
Проект Джода-Тайм, теперь в Режим технического обслуживания, советует перейти на классы java.time.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте Драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в классах java.sql.*.
Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и более.
Как было сказано выше, при этом теряется часовой пояс, содержащийся в Date.