Das Problem ist, dass ich einen Webdienst-Client aus einer Datei erstellen muss, die mir bereitgestellt wurde. Ich habe diese Datei im lokalen Dateisystem gespeichert und während ich die WSDL-Datei im richtigen Dateisystemordner behalte, ist alles in Ordnung. Wenn ich es auf einem Server bereitstelle oder die WSDL aus dem Dateisystemordner entferne, kann der Proxy die WSDL nicht finden und es tritt ein Fehler auf. Ich habe das Web durchsucht und die folgenden Beiträge gefunden, aber ich konnte es nicht zum Laufen bringen:
JAX-WS Laden von WSDL aus dem Jar
http://www.java.net/forum/topic/glassfish/metro -and-jaxb / client-jar-cant-find-local-wsdl-0
http://blog.vinodsingh.com/2008/12/locally-packaged-wsdl.html
Ich verwende NetBeans 6.1 (dies ist eine Legacy-Anwendung, die ich mit diesem neuen Webdienst-Client aktualisieren muss). Unten finden Sie die JAX-WS-Proxy-Klasse:
@WebServiceClient(name = "SOAService", targetNamespace = "http://soaservice.eci.ibm.com/", wsdlLocation = "file:/C:/local/path/to/wsdl/SOAService.wsdl")
public class SOAService
extends Service
{
private final static URL SOASERVICE_WSDL_LOCATION;
private final static Logger logger = Logger.getLogger(com.ibm.eci.soaservice.SOAService.class.getName());
static {
URL url = null;
try {
URL baseUrl;
baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource(".");
url = new URL(baseUrl, "file:/C:/local/path/to/wsdl/SOAService.wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'file:/C:/local/path/to/wsdl/SOAService.wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SOASERVICE_WSDL_LOCATION = url;
}
public SOAService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SOAService() {
super(SOASERVICE_WSDL_LOCATION, new QName("http://soaservice.eci.ibm.com/", "SOAService"));
}
/**
* @return
* returns SOAServiceSoap
*/
@WebEndpoint(name = "SOAServiceSOAP")
public SOAServiceSoap getSOAServiceSOAP() {
return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class);
}
/**
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* @return
* returns SOAServiceSoap
*/
@WebEndpoint(name = "SOAServiceSOAP")
public SOAServiceSoap getSOAServiceSOAP(WebServiceFeature... features) {
return super.getPort(new QName("http://soaservice.eci.ibm.com/", "SOAServiceSOAP"), SOAServiceSoap.class, features);
}
}
Dies ist mein Code zur Verwendung des Proxys:
WebServiceClient annotation = SOAService.class.getAnnotation(WebServiceClient.class);
// trying to replicate proxy settings
URL baseUrl = com.ibm.eci.soaservice.SOAService.class.getResource("");//note : proxy uses "."
URL url = new URL(baseUrl, "/WEB-INF/wsdl/client/SOAService.wsdl");
//URL wsdlUrl = this.getClass().getResource("/META-INF/wsdl/SOAService.wsdl");
SOAService serviceObj = new SOAService(url, new QName(annotation.targetNamespace(), annotation.name()));
proxy = serviceObj.getSOAServiceSOAP();
/* baseUrl;
//classes\com\ibm\eci\soaservice
//URL url = new URL(baseUrl, "../../../../wsdl/SOAService.wsdl");
proxy = new SOAService().getSOAServiceSOAP();*/
//updating service endpoint
Map<String, Object> ctxt = ((BindingProvider)proxy ).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WebServiceUrl);
NetBeans hat eine Kopie der WSDL in web-inf / wsdl / client / SOAService abgelegt , daher möchte ich sie nicht auch zu META-INF hinzufügen . Serviceklassen sind in WEB-INF / classes / com / ibm / eci / soaservice / und die Variable baseurl enthält den vollständigen Pfad des Dateisystems (c: \ path \ to \ the \ project ... \ soaservice). Der obige Code löst den Fehler aus:
javax.xml.ws.WebServiceException: Zugriff auf die WSDL fehlgeschlagen unter: file: /WEB-INF/wsdl/client/SOAService.wsdl. Es ist fehlgeschlagen mit: \ WEB-INF \ wsdl \ client \ SOAService.wsdl (Pfad kann nicht gefunden werden)
Soll ich also zuerst die wsdllocation der Proxy-Klasse aktualisieren? Wie kann ich dann die SOAService-Klasse in WEB-INF / classes / com / ibm / eci / soaservice anweisen, in \ WEB-INF \ wsdl \ client \ SOAService.wsdl nach der WSDL zu suchen?
BEARBEITET : Ich habe diesen anderen Link gefunden - http://jianmingli.com/wp/?cat=41 , der besagt , dass die WSDL in den Klassenpfad eingefügt werden soll. Ich schäme mich zu fragen: Wie füge ich es in den Klassenpfad der Webanwendung ein?
Antworten:
Die beste Option ist die Verwendung von jax-ws-catalog.xml
Wenn Sie die lokale WSDL-Datei kompilieren, überschreiben Sie den WSDL-Speicherort und setzen Sie ihn auf so etwas wie
Machen Sie sich keine Sorgen, dies ist nur eine URI und keine URL, dh Sie müssen die WSDL nicht an dieser Adresse verfügbar haben.
Sie können dies tun, indem Sie die Option wsdllocation an wsdl an den Java-Compiler übergeben.
Dadurch wird Ihr Proxy-Code von geändert
zu
Hinweisdatei: // im URL-Konstruktor in http: // geändert.
Jetzt kommt in jax-ws-catalog.xml. Ohne jax-ws-catalog.xml wird jax-ws tatsächlich versuchen, die WSDL vom Speicherort zu laden
und scheitern, da keine solche WSDL verfügbar sein wird.Mit jax-ws-catalog.xml können Sie jax-ws jedoch zu einer lokal gepackten WSDL umleiten, wenn versucht wird, auf die WSDL @ zuzugreifen
.Hier ist jax-ws-catalog.xml
Was Sie tun, ist jax-ws mitzuteilen, dass WSDL von wann immer geladen werden muss
sollte es vom lokalen Pfad wsdl / SOAService.wsdl geladen werden.Wo sollten Sie nun wsdl / SOAService.wsdl und jax-ws-catalog.xml ablegen? Das ist die Millionen-Dollar-Frage, nicht wahr?
Es sollte sich im META-INF-Verzeichnis Ihrer Anwendungs-JAR befinden.
so etwas wie das
Auf diese Weise müssen Sie nicht einmal die URL in Ihrem Client überschreiben, die auf den Proxy zugreift. Die WSDL wird aus Ihrer JAR abgerufen, und Sie müssen keine fest codierten Dateisystempfade in Ihrem Code haben.
Weitere Informationen unter jax-ws-catalog.xml http://jax-ws.java.net/nonav/2.1.2m1/docs/catalog-support.html
hoffentlich hilft das
quelle
Ein anderer Ansatz, den wir erfolgreich gewählt haben, besteht darin, den WS-Client-Proxy-Code mit wsimport (von Ant als Ant-Task) zu generieren und das Attribut wsdlLocation anzugeben.
Da wir dies für ein Projekt mit mehreren WSDLs ausführen, löst das Skript den Wert $ (wsdl.file} dynamisch auf, der als /META-INF/wsdl/YourWebServiceName.wsdl relativ zum JavaSource-Speicherort (oder / src,) eingerichtet ist. Abhängig davon, wie Sie Ihr Projekt eingerichtet haben.) Während des Erstellungsprozesses werden die WSDL- und XSDs-Dateien an diesen Speicherort kopiert und in die JAR-Datei gepackt (ähnlich der oben von Bhasakar beschriebenen Lösung).
Hinweis: Stellen Sie sicher, dass die WSDL-Dateien relative Referenzen für importierte XSDs und keine http-URLs verwenden:
Im generierten Code finden wir Folgendes:
Vielleicht könnte das auch helfen. Es ist nur ein anderer Ansatz, der nicht den "Katalog" -Ansatz verwendet.
quelle
Vielen Dank für die Antwort von Bhaskar Karambelkar, die mein Problem ausführlich erklärt und behoben hat. Aber ich möchte auch die Antwort in drei einfachen Schritten für jemanden umformulieren, der es eilig hat, sie zu reparieren
wsdlLocation= "http://localhost/wsdl/yourwsdlname.wsdl"
Erstellen Sie eine XML-Datei jax-ws-catalog.xml unter META-INF wie folgt
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system"> <system systemId="http://localhost/wsdl/yourwsdlname.wsdl" uri="wsdl/yourwsdlname.wsdl" /> </catalog>
Verpacken Sie jetzt Ihr Glas. Kein Verweis mehr auf das lokale Verzeichnis, es ist alles gepackt und referenziert
quelle
Für diejenigen unter Ihnen, die Spring verwenden, können Sie einfach mit dem Klassenpfadprotokoll auf eine beliebige Klassenpfadressource verweisen. Im Fall von wsdlLocation wird dies also:
Beachten Sie, dass dies kein Standardverhalten von Java ist. Siehe auch: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html
quelle
Für diejenigen, die hier noch nach einer Lösung suchen, wäre die einfachste Lösung, sie zu verwenden
<wsdlLocation>
, ohne Code zu ändern. Arbeitsschritte sind unten angegeben: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):
Der Vollständigkeit halber stelle ich hier einen vollständigen Teil der Codegenerierung mit einer fließenden API für generierten Code bereit.
quelle
Hatte genau das gleiche Problem, das hier beschrieben wird. Unabhängig davon, was ich gemäß den obigen Beispielen getan habe, um den Speicherort meiner WSDL-Datei (in unserem Fall von einem Webserver) zu ändern, wurde immer noch auf den ursprünglichen Speicherort verwiesen, der in den Quellbaum des Serverprozesses eingebettet ist.
Nach VIELEN Stunden beim Versuch, dies zu debuggen, bemerkte ich, dass die Ausnahme immer aus genau derselben Zeile ausgelöst wurde (in meinem Fall 41). Schließlich habe ich heute Morgen beschlossen, meinen Quell-Client-Code einfach an unseren Handelspartner zu senden, damit dieser zumindest verstehen kann, wie der Code aussieht, aber vielleicht seinen eigenen erstellen kann. Zu meinem Schock und Entsetzen fand ich eine Reihe von Klassendateien, die mit meinen .java-Dateien in meinem Client-Quellbaum gemischt waren. Wie bizarr !! Ich vermute, dass dies ein Nebenprodukt des JAX-WS-Client-Builder-Tools war.
Sobald ich diese albernen .class-Dateien gezappt und eine vollständige Bereinigung und Neuerstellung des Client-Codes durchgeführt habe, funktioniert alles perfekt !! Redonculous !!
YMMV, Andrew
quelle