Wenn ich einen Webservice-Client mit wsdl2java aus CXF (der etwas Ähnliches wie wsimport generiert) über maven generiere, beginnen meine Dienste mit folgenden Codes:
@WebServiceClient(name = "StatusManagement",
wsdlLocation = "c:/some_absolute_path_to_a_wsdl_file.wsdl",
targetNamespace = "http://tempuri.org/")
public class StatusManagement extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
static {
URL url = null;
try {
url = new URL("c:/some_absolute_path_to_a_wsdl_file.wsdl");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from c:/some_absolute_path_to_a_wsdl_file.wsdl");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
Der fest codierte absolute Pfad ist wirklich scheiße. Die generierte Klasse funktioniert auf keinem anderen Computer als meinem.
Die erste Idee ist, die WSDL-Datei (plus alles, was sie importiert, andere WSDLs und XSDs) irgendwo in eine JAR-Datei zu legen und sie zu klassifizieren. Aber das wollen wir vermeiden. Da all das von CXF und JAXB basierend auf den WSDLs und XSDs generiert wurde, sehen wir keinen Grund, die WSDL zur Laufzeit kennen zu müssen.
Das wsdlLocation-Attribut soll den WSDL-Speicherort überschreiben (zumindest habe ich dies irgendwo gelesen), und der Standardwert ist "". Da wir maven verwenden, haben wir versucht, <wsdlLocation></wsdlLocation>
in die Konfiguration von CXF aufzunehmen, um den Quellgenerator zu zwingen, die wsdlLocation leer zu lassen. Dadurch wird das XML-Tag jedoch einfach ignoriert, da es leer ist. Wir haben einen wirklich hässlichen, beschämenden Hack gemacht <wsdlLocation>" + "</wsdlLocation>
.
Dies ändert auch andere Orte:
@WebServiceClient(name = "StatusManagement",
wsdlLocation = "" + "",
targetNamespace = "http://tempuri.org/")
public class StatusManagement extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
static {
URL url = null;
try {
url = new URL("" + "");
} catch (MalformedURLException e) {
System.err.println("Can not initialize the default wsdl from " + "");
// e.printStackTrace();
}
WSDL_LOCATION = url;
}
Meine Fragen sind also:
Benötigen wir wirklich einen WSDL-Speicherort, auch wenn alle Klassen von CXF und JAXB generiert wurden? Wenn ja, warum?
Wenn wir den WSDL-Speicherort nicht wirklich benötigen, wie kann CXF ihn dann ordnungsgemäß und sauber nicht generieren und vollständig vermeiden?
Welche schlimmen Nebenwirkungen könnten wir mit diesem Hack bekommen? Wir können das immer noch nicht testen, um zu sehen, was passiert. Wenn also jemand im Voraus sagen könnte, wäre es schön.
classpath:
in der<wsdlLocation...
Zeile weg .Wir gebrauchen
Verwenden Sie mit anderen Worten einen Pfad relativ zum Klassenpfad.
Ich glaube, dass die WSDL zur Laufzeit zur Validierung von Nachrichten während des Marschalls / Unmarschalls benötigt wird.
quelle
Für diejenigen, die
org.jvnet.jax-ws-commons:jaxws-maven-plugin
zum Erstellen eines Clients aus WSDL zur Erstellungszeit Folgendes verwenden:src/main/resources
wsdlLocation
mitclasspath:
wsdlLocation
mit voran/
Beispiel:
/src/main/resources/foo/bar.wsdl
jaxws-maven-plugin
mit<wsdlDirectory>${basedir}/src/main/resources/foo</wsdlDirectory>
und<wsdlLocation>/foo/bar.wsdl</wsdlLocation>
quelle
1) In einigen Fällen ja. Wenn die WSDL beispielsweise Richtlinien enthält, die das Laufzeitverhalten steuern, ist die WSDL möglicherweise zur Laufzeit erforderlich. Artefakte werden nicht für politikbezogene Dinge und dergleichen generiert. In einigen obskuren RPC / Literal-Fällen werden nicht alle benötigten Namespaces im generierten Code ausgegeben (pro Spezifikation). Somit würde die wsdl für sie benötigt. Obskure Fälle.
2) Ich dachte so etwas würde funktionieren. Welche Version von CXF? Das klingt nach einem Fehler. Sie können dort eine leere Zeichenfolge versuchen (nur Leerzeichen). Ich bin mir nicht sicher, ob das funktioniert oder nicht. In Ihrem Code können Sie jedoch den Konstruktor verwenden, der die WSDL-URL verwendet und einfach null übergibt. Die wsdl würde nicht verwendet.
3) Nur die oben genannten Einschränkungen.
quelle
Ich konnte generieren
indem Sie die pom-Datei so konfigurieren, dass sie eine Null für wsdlurl hat:
quelle
Ist es möglich, dass Sie die Verwendung von wsdl2java vermeiden können? Sie können sofort CXF FrontEnd-APIs verwenden, um Ihren SOAP-Webservice aufzurufen. Der einzige Haken ist, dass Sie Ihre SEI und VOs auf Ihrer Client-Seite erstellen müssen. Hier ist ein Beispielcode.
Das vollständige Tutorial finden Sie hier http://weblog4j.com/2012/05/01/developing-soap-web-service-using-apache-cxf/
quelle
Update für CXF 3.1.7
In meinem Fall habe ich die WSDL-Dateien abgelegt
src/main/resources
und diesen Pfad zu meinen Srouces in Eclipse hinzugefügt (Rechtsklick auf Projekt-> Erstellungspfad -> Erstellungspfad konfigurieren ...-> Quelle [Tab] -> Ordner hinzufügen).So sieht meine
pom
Datei aus und wie zu sehen ist, ist KEINEwsdlLocation
Option erforderlich:Und hier ist der generierte Service. Wie zu sehen ist, stammt die URL von ClassLoader und nicht vom Absolute File-Path
quelle
<configuration> <sourceRoot>${basedir}/src/main/java/</sourceRoot> <wsdlRoot>${basedir}/src/main/resources/</wsdlRoot> <includes> <include>*.wsdl</include> </includes> </configuration>
Ich füge alle .wsdl-Dateien in den Klassenpfad ein. Wie kann ich dann den wsdl-Speicherort angeben, damit jede generierte .java-Datei den jeweiligen .wsdl-Pfad enthält? Danke im Voraus. @ MazyIm Ernst, die beste Antwort funktioniert bei mir nicht. versuchte cxf.version 2.4.1 und 3.0.10. und generiere jedes Mal einen absoluten Pfad mit wsdlLocation.
Meine Lösung besteht darin, den
wsdl2java
Befehl in derapache-cxf-3.0.10\bin\
mit zu verwenden-wsdlLocation classpath:wsdl/QueryService.wsdl
.Detail:
quelle
@ Martin Devillers Lösung funktioniert gut. Geben Sie der Vollständigkeit halber die folgenden Schritte an:
src/main/resource
Fügen Sie in der POM-Datei sowohl wsdlDirectory als auch wsdlLocation hinzu (nicht verpassen / am Anfang von wsdlLocation), wie unten. Während wsdlDirectory zum Generieren von Code verwendet wird und wsdlLocation zur Laufzeit zum Erstellen eines dynamischen Proxys verwendet wird.
Dann in Ihrem Java-Code (mit No-Arg-Konstruktor):
Hier ist der vollständige Teil der Codegenerierung in der POM-Datei mit einer fließenden API im generierten Code.
quelle