Java 1.6 verwenden wsimport
Ich habe den Quellcode aus einer WSDL für einen Webdienst generiert. Eines der Felder in der Anforderungsstruktur hat den Typ xs:dateTime
im XML-Schema, das die WSDL enthält, und Typ javax.xml.datatype.XMLGregorianCalendar
im generierten Code.
Durch manuelle Tests mit soapUI habe ich festgestellt, dass die folgenden serialisierten Werte vom Webdienst akzeptiert werden: 2011-12-08
, 2011-12-08Z
. Die folgenden Angaben werden nicht akzeptiert und die Antwort ist in diesem Fall eine leere Antwort (kein expliziter Fehler): 2011-12-08T20:00:00
, 2011-12-08T20:00:00-05:00
. Der Dienst selbst ist .NET-basiert, falls das eine Rolle spielt.
Mein Gedanke ist, dass der Server das vollständige Datum und die Uhrzeit akzeptieren und nur das Datum zurückweisen sollte, aber genau das Gegenteil ist der Fall. Aber ich gehe nicht davon aus, dass die Betreiber des Servers offen für Änderungen sind. Also habe ich versucht, den Client davon zu überzeugen, nur ein Datum zu senden.
Ich kann meinen Client-Code nicht dazu bringen, eine XMLGregorianCalendar
Objekt nur in ein Datum umwandeln. Nun, eigentlich kann ich das, außer wenn der generierte Code dies tut. Wenn der generierte Client-Code (erzeugt von wsimport
), ist der serialisierte Wert eine leere Zeichenkette, und der Server gibt korrekt einen Fehler zurück. Ich habe dies mit einem Packet Sniffer überprüft.
Im Folgenden wird beschrieben, wie ich das Datumsfeld in der Anfrage erstelle und auffülle:
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;
}
Die Implementierungsklasse für XMLGregorianCalendar lautet in meinem Fall com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl
. Im Debugger, oder wenn ich eine Log-Ausgabe hinzufüge, wird der Aufruf des Datumsobjekts toXMLFormat()
Methode gibt nur ein Datum zurück, z. B. 2011-12-09
. Wenn ich einen Debugger verwende, um das Datumsobjekt selbst zu untersuchen, sehe ich, dass sein year
, day
y month
Felder sind ausgefüllt, und alle anderen sind entweder null
o -2147483648
das ist der Wert von DatatypeConstants.FIELD_UNDEFINED
. Nach allen Unterlagen und Internet-Suchergebnissen, die ich gefunden habe, ist mein Datumsobjekt korrekt geformt.
Bin ich verrückt? Ist der Server wirklich im Irrtum? Ist die Weigerung des generierten Client-Codes, nur ein Datum zu senden, korrekt? Ist dies ein vertretbarer Fall von "undefiniertem Verhalten"? Wird die falsche Implementierungsklasse verwendet (könnte das überhaupt eine Rolle spielen)? Gibt es ein bekanntes Problem mit wsimport
die sich auf mich auswirkt?