Tipps zur Fehlerbehebung bei der Serialisierung und Entserialisierung von Web-Services
Verwenden Sie die folgenden Tipps, Probleme zu beheben, die bei der Serialisierung und Entserialisierung in Web-Services auftreten können.
Jeder Abschnitt dieses Artikels beschreibt ein Problem, das bei der Serialisierung oder Entserialisierung von Web-Services auftreten kann. Zur Unterstützung der Fehlerbehebung werden Lösungsvorschläge angeboten.
Die Zeitzoneninformationen im entserialisierten java.util.Calendar sind nicht wie erwartet
Wenn der Client und der Server auf Java™-Code basieren und eine java.util.Calendar-Instanz empfangen wird, kann die Zeitzone in der empfangenen java.util.Calendar-Instanz von der Zeitzone in der gesendeten java.util.Calendar-Instanz abweichen.
Dieser Fehler tritt auf, weil java.util.Calendar für die Übertragung als xsd:dateTime codiert wird. xsd:dateTime ist zwar zum Codieren der Zeit (Basiszeit plus oder minus Zeitzonendifferenz), aber nicht für die Übernahme der Ländereinstellungen erforderlich, zu denen die ursprüngliche Zeitzone gehört.
java.util.Calendar c1 = ...// Datum und Uhrzeit in Zeitzone 1
java.util.Calendar c2 = ...// Selbes Datum und selbe Uhrzeit, aber in Zeitzone 2
// c1 und c2 sind nicht identisch, weil die Zeitzonen unterschiedlich sind
if (c1.equals (c2)) System.out.println("c1 und c2 sind identisch");
// c1 und c2 lassen sich mit "not before and not after" vergleichen, weil
sie dasselbe Datum und dieselbe Uhrzeit darstellen
if (!c1.after(c2) & !c1.before(c2) {
System.out.println("c1 und c2 sind identisch");
}
Zusammenführen von Web-Service-Client- und -Serverbindungen führt zu Fehlern
Die Spezifikationen Web Services for Java Platform, Enterprise Edition (Java EE) und Java API for XML-based Remote Procedure Call (JAX-RPC) bieten keine Unterstützung für die gegenseitige Zuordnung zwischen Java-Code und einem WSDL-Dokument (Web Services Description Language) für alle Java-Typen. Beispielsweise ist es nicht möglich, ein Java-Date in XML-Code zu konvertieren (serialisieren) und dann wieder zurück in ein Java-Date zu konvertieren (entserialisieren). Die Entserialisierung erfolgt mit dem Java-Calendar.
Wenn Sie mit einer Java-Implementierung arbeiten, aus der Sie ein WSDL-Dokument erstellen, und die Clientbindungen aus dem WSDL-Dokument generieren, können die Clientklassen von den Serverklassen abweichen, selbst wenn die Clientklassen dieselben Paket- und Klassennamen haben. Der Klassen des Web-Service-Client müssen getrennt von den Klassen des Web-Service-Servers verwaltet werden. Beispiel: Wenn Sie die Bindungsklassen des Web-Service-Servers in die JAR-Datei eines Dienstprogramms einfügen, dürfen Sie nicht anschließend die JAR-Datei des Web-Service-Clients einfügen, die auf dieselbe JAR-Dienstprogrammdatei verweist.
com.ibm.ws.webservices.engine.PivotHandlerWrapper TRAS0014I: Die folgende Ausnahme wurde
protokolliert: java.lang.NoSuchMethodError: com.ibm.wssvt.acme.websvcs.ExtWSPolicyData:
method getStartDate()Ljava/util/Date;
not found
at com.ibm.wssvt.acme.websvcs.ExtWSPolicyData_Ser.addElements(ExtWSPolicyData_Ser.java: 210)
at com.ibm.wssvt.acme.websvcs.ExtWSPolicyData_Ser.serialize (ExtWSPolicyData_Swer.java:29)
at com.ibm.ws.webservices.engine.encoding.SerializationContextImpl.serializeActual
(SerializationContextImpl.java 719)
at com.ibm.ws.webservices.engine.encoding.SerializationContextImpl.serialize
(SerializationContextImpl.java: 463)
Das Problem
ist auf die Verwendung einer Schnittstelle zurückzuführen, wie das folgende Beispiel
für die Serviceendpunktschnittstelle in der Serviceimplementierung zeigt:
package server:
public interface Test_SEI extends java.rmi.Remote {
public java.util.Calendar getCalendar () throws java.rmi.RemoteException;
public java.util.Date getDate() throws java.rmi.RemoteException;
}
Wenn diese Schnittstelle mit dem Befehlszeilentool
Java2WSDL kompiliert und ausgeführt wird, ordnet das
WSDL-Dokument die Methoden wie folgt zu:<wsdl:message name="getDateResponse">
<wsdl:part name="getDateReturn" type="xsd:dateTime"/>
</wsdl:message>
<wsdl:message name="getCalendarResponse">
<wsdl:part name="getCalendarReturn" type="xsd:dateTime"/>
</wsdl:message>
Die vom Tool Java2WSDL implementierte JAX-RPC-Zuordnung
ordnet sowohl java.util.Date- als auch java.util.Calendar-Instanzen
dem XML-Typ xsd:dateTime zu.
Im nächsten Schritt wird die generierte WSDL-Datei verwendet, um einen Client für den Web-Service zu erstellen. Wenn Sie das Tool WSDL2Java
für die generierte WSDL-Datei ausführen, enthalten die generierten
Klassen eine andere Version der Schnittstelle server.Test_SEI, z. B.:package server;
public interface Test_SEI extends java.rmi.Remote {
public java.util.Calendar getCalendar() throws java.rmi.RemoteException;
public java.util.Calendar getDate() throws java.rmi.RemoteException;
}
Die Clientversion der Schnittstelle service.Test_SEI unterscheidet sich insofern von der Serverversion, dass die Methoden getCalendar und getDate beide java.util.Calendar zurückgeben. Der vom Client erwartete Serialisierungs- und Entserialisierungscode ist die Clientversion der Serviceendpunktschnittstelle. Sollte während der Kompilierung oder Ausführung im Klassenpfad des Clients versehentlich die Serverversion enthalten sein, tritt ein Fehler auf.
Zusätzlich zum Fehler NoSuchMethod können IncompatibleClassChangeError und ClassCastException ausgegeben werden. Im Prinzip kann jedoch jede Laufzeitausnahme eintreten. Es wird dringend empfohlen, die Bindungsklassen des Web-Service-Clients von den Bindungsklassen des Web-Service-Servers zu trennen. Verwenden Sie stets separate Module für die Clientbindungsklassen und die Serverbindungsklassen. Wenn diese Bindungsklassen in derselben Anwendung verwendet werden, kopieren Sie die Bindungsklassen in JAR-Dienstprogrammdateien, die von den Modulen nicht gemeinsam genutzt werden.