Webservice: type='xs:anyType': wie funktioniert das?

superomega

Grünschnabel
Hallo,

ich möchte in einem Webservice (JAX-WS) Datentypen benutzen, die mir zur Entwicklungszeit des WS-Schemas nicht bekannt sind.
Dafür gibt es doch den Typen 'anyType'. Leider komme ich nicht dahinter, wie ich den Typen richtig benutzen kann.
Meine Testfunktion funktioniert mit allen klar definierten DatenTypen, sobald ich ein Objekt in das Feld vom Typ anytype einhänge,
bekomme ich diese Fehlermeldung:

javax.xml.bind.JAXBException: class org.wh.ws.any.Buergermeister nor any of its super class is known to this context.

Dabei habe ich für die Klasse Buergermeister ein .xsd File geschrieben und mit der wsdl mit wsimport kompiliert.
Die Klasse Buergermeister ist der Objectfactory also bekannt. Warum funktioniert es dann trotzdem nicht?
Die Anwendung läuft in JBoss 5.0.1

Viele Grüße,
Werner

Die WSDL:
Code:
<definitions name='WSAnyService' targetNamespace='http://any.ws.wh.org/' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://any.ws.wh.org/' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
 <types>
     <xsd:schema>
        <xsd:import namespace="http://any.ws.wh.org/" schemaLocation="model.xsd"/>
     </xsd:schema>
 </types>
 <message name='WSAny_searchCity'>
  <part element='tns:searchCity' name='searchCity'></part>
 </message>
 <message name='WSAny_searchCityResponse'>
  <part element='tns:searchCityResponse' name='searchCityResponse'></part>
 </message>
 <portType name='WSAny'>
  <operation name='searchCity' parameterOrder='searchCity'>
   <input message='tns:WSAny_searchCity'></input>
   <output message='tns:WSAny_searchCityResponse'></output>
  </operation>
 </portType>
 <binding name='WSAnyBinding' type='tns:WSAny'>
  <soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
  <operation name='searchCity'>
   <soap:operation soapAction=''/>
   <input>
    <soap:body use='literal'/>
   </input>
   <output>
    <soap:body use='literal'/>
   </output>
  </operation>
 </binding>
 <service name='WSAnyService'>
  <port binding='tns:WSAnyBinding' name='WSAnyPort'>
   <soap:address location='http://HELIOTROP:8080/WSAnyType/WSAny'/>
  </port>
 </service>
</definitions>

Das Model:
Code:
<?xml version="1.0" encoding="UTF-8"?>
  <xs:schema targetNamespace='http://any.ws.wh.org/' version='1.0' xmlns:tns='http://any.ws.wh.org/' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
   <xs:element name='searchCity' type='tns:searchCity'/>
   <xs:element name='searchCityResponse' type='tns:searchCityResponse'/>
   <xs:complexType name='searchCity'>
    <xs:sequence>
     <xs:element minOccurs='0' name='name' type='xs:string'/>
    </xs:sequence>
   </xs:complexType>
   <xs:complexType name='searchCityResponse'>
    <xs:sequence>
     <xs:element minOccurs='0' name='return' type='tns:stadt'/>
    </xs:sequence>
   </xs:complexType>
   <xs:complexType name='stadt'>
    <xs:sequence>
     <xs:element minOccurs='0' name='name' type='xs:string'/>
     <xs:element minOccurs='0' name='verkehrssystem' type='tns:verkehrssystem'/>
    </xs:sequence>
   </xs:complexType>
   <xs:complexType name='verkehrssystem'>
    <xs:sequence>
     <xs:element minOccurs='0' name='id' type='xs:int'/>
     <xs:element minOccurs='0' name='infrastruktur' type='xs:anyType'/>
    </xs:sequence>
   </xs:complexType>
   <xs:complexType name='buergermeister'>
    <xs:sequence>
     <xs:element minOccurs='0' name='name' type='xs:string'/>
    </xs:sequence>
   </xs:complexType>
  </xs:schema>

Der Server:
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.wh.ws.any.ejb;

import org.wh.ws.any.Stadt;
import org.wh.ws.any.Verkehrssystem;
import org.wh.ws.any.Buergermeister;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;

/**
 *
 * @author Hofmann
 */
@WebService(serviceName = "WSAnyService", portName = "WSAnyPort", endpointInterface = "org.wh.ws.any.WSAny", targetNamespace = "http://any.ws.wh.org/", wsdlLocation = "META-INF/wsdl/WSAnyType/WSAny.wsdl")
@XmlSeeAlso({Buergermeister.class})
@Stateless
public class WSAnyType {

  public org.wh.ws.any.Stadt searchCity(java.lang.String name)
  {
    Stadt stadt = new Stadt();
    stadt.setName("Nowhere");
    Verkehrssystem v = new Verkehrssystem();
    stadt.setVerkehrssystem(v);
    v.setId(23);
    Buergermeister b = new Buergermeister();
    b.setName("Ole");
    Stadt s = new Stadt();
    v.setInfrastruktur(b);

    return stadt;
  }

}
 
Zuletzt bearbeitet:
So, ich habe jetzt folgende Lösung:

die Datenstrukturen ab anyType stecke ich z.B. in ein extra .xsd. Damit kann jeder seine eigenen DatenSchematas entwickeln und zum Programm dazulegen.
Im Server baue ich den DatenBaum auf und marshalle ihn anschließend.
Die ObjectFactory zum un/marshallen kommt aus der externen DatenLibrary.
Das Ergebnis füge ich in das anyType-Feld ein.

Code:
    try
    {
      org.wh.ws.any.data.ObjectFactory fac = new org.wh.ws.any.data.ObjectFactory();

      JAXBContext jc = JAXBContext.newInstance(fac.getClass());
      Marshaller m = jc.createMarshaller();
      Unmarshaller um = jc.createUnmarshaller();

      StringWriter sw = new StringWriter();
      m.marshal(b, sw);
      sB = sw.toString();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }


    v.setInfrastruktur(sB);

auf der ClientSeite hole ich mir den Inhalt vom anyType-Feld und unmarshalle den String:
Code:
    Object obj = stadt.getVerkehrssystem().getInfrastruktur();

    try
    {
      org.wh.ws.any.data.ObjectFactory fac = new org.wh.ws.any.data.ObjectFactory();

      JAXBContext jc = JAXBContext.newInstance(fac.getClass());
      Unmarshaller um = jc.createUnmarshaller();

      ByteArrayInputStream xmlContent = new ByteArrayInputStream(obj.toString().getBytes());
      Buergermeister unmarshalledObj = (Buergermeister)um.unmarshal(xmlContent);
      System.out.println("Obj = " + unmarshalledObj);
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }

Wer hat eine Idee für eine einfachere Lösung?

Viele Grüße,
Werner
 
Zurück