Использование Java 1.6 wsimport
Я сгенерировал исходный код из WSDL для веб-службы. Одно из полей в структуре запроса имеет тип xs:dateTime
в схеме XML, включенной в WSDL, и тип javax.xml.datatype.XMLGregorianCalendar
в сгенерированном коде.
Путем ручного тестирования с помощью soapUI я определил, что веб-сервисом принимаются следующие сериализованные значения: 2011-12-08
, 2011-12-08Z
. Следующее не принимается, и ответ в этом случае является пустым ответом (не явной ошибкой): 2011-12-08T20:00:00
, 2011-12-08T20:00:00-05:00
. Сам сервис работает на платформе .NET, если это имеет значение.
Я думаю, что сервер должен принять полную дату / время и отклонить только дату, но наоборот - то, что происходит. Но я не думаю, что сопровождающие сервера будут открыты для изменений. Поэтому я попытался убедить клиента отправить только дату.
Я не могу убедить мой клиентский код сериализовать объект XMLGregorianCalendar
только в дату. Ну, на самом деле я могу, за исключением , когда сгенерированный код делает это. Когда сгенерированный код клиента (созданный wsimport
) делает это, сериализованное значение является пустой строкой, и сервер правильно возвращает ошибку. Я проверил это с помощью анализатора пакетов.
Вот как я создаю и заполняю поле даты в запросе:
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.util.TimeZone;
// also import GeneratedRequest from generated packages
private makeRequest() {
GeneratedRequest request;
// ...
request.setDateField(xmlDayNow(TimeZone.getTimeZone("America/New_York"),
6)); // broadcast day starts at 6 am EST
// ...
}
@XmlSchemaType(name="date")
private static XMLGregorianCalendar xmlDayNow(TimeZone tz, int localHourStart)
throws MyException {
GregorianCalendar cal = gregorianBroadcastDayNow(tz, localHourStart);
XMLGregorianCalendar result;
try {
result = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(
cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1,
cal.get(Calendar.DAY_OF_MONTH), DatatypeConstants.FIELD_UNDEFINED)
.normalize();
} catch (DatatypeConfigurationException e) {
throw new MyException("XMLGregorianCalendar issue", e);
}
return result;
}
protected static GregorianCalendar gregorianBroadcastDayNow(TimeZone tz,
int localHourStart) {
GregorianCalendar now = new GregorianCalendar(tz);
if (now.get(GregorianCalendar.HOUR_OF_DAY) < localHourStart) {
now.add(GregorianCalendar.DAY_OF_MONTH, -1);
}
return now;
}
Класс реализации для XMLGregorianCalendar в моем случае - com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl
. В отладчике или, если я добавляю вывод журнала, вызов метода toXMLFormat()
объекта даты возвращает только дату, такую как 2011-12-09
. Используя отладчик для проверки самого объекта даты, я вижу, что его поля year
, day
и month
заполнены, а все остальные - либо null
, либо -2147483648
, что является значением DatatypeConstants.FIELD_UNDEFINED
, Согласно всей найденной мной документации и результатам поиска в Интернете, мой объект даты сформирован правильно.
Я сумасшедший? Сервер действительно в ошибке? Является ли отказ от сгенерированного клиентского кода отправкой даты только правильным? Это оправданный случай "неопределенного поведения"? Используется ли неправильный класс реализации (может ли это иметь значение в любом случае)? Есть ли какая-то известная проблема с wsimport
, которая затрагивает меня?