Kiedy generuję klienta webservice za pomocą wsdl2java z CXF (który generuje coś podobnego do wsimport), za pośrednictwem maven, moje usługi zaczynają się od takich kodów:
@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;
}
Zakodowana na stałe ścieżka absolutna naprawdę jest do niczego. Wygenerowana klasa nie będzie działać na żadnym innym komputerze niż mój.
Pierwszym pomysłem jest umieszczenie pliku WSDL (plus wszystko, co importuje, inne WSDL i XSD) gdzieś w pliku jar i to w ścieżce klas. Ale chcemy tego uniknąć. Ponieważ wszystko to zostało wygenerowane przez CXF i JAXB oparte na plikach WSDL i XSD, nie widzimy potrzeby znajomości WSDL w czasie wykonywania.
Atrybut wsdlLocation ma na celu przesłonięcie położenia WSDL (przynajmniej to gdzieś przeczytałem) i jego domyślną wartością jest „”. Ponieważ używamy maven, próbowaliśmy dołączyć <wsdlLocation></wsdlLocation>
do konfiguracji CXF, aby spróbować zmusić generator źródłowy do pozostawienia pustego miejsca wsdlLocation. Jednak to po prostu powoduje, że ignoruje znacznik XML, ponieważ jest pusty. Zrobiliśmy naprawdę brzydki, haniebny hack, używając <wsdlLocation>" + "</wsdlLocation>
.
To zmienia również inne miejsca:
@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;
}
Więc moje pytania to:
Czy naprawdę potrzebujemy lokalizacji WSDL, nawet jeśli wszystkie klasy zostały wygenerowane przez CXF i JAXB? Jeśli tak, dlaczego?
Jeśli naprawdę nie potrzebujemy lokalizacji WSDL, jaki jest właściwy i czysty sposób, aby CXF jej nie generował i całkowicie jej unikał?
Jakie złe skutki uboczne moglibyśmy uzyskać dzięki temu włamaniu? Nadal nie możemy tego przetestować, aby zobaczyć, co się stanie, więc gdyby ktoś mógł powiedzieć z góry, byłoby miło.
classpath:
w<wsdlLocation...
wierszu.Używamy
Innymi słowy, użyj ścieżki względnej do ścieżki klas.
Uważam, że WSDL może być potrzebny w czasie wykonywania do sprawdzania poprawności komunikatów podczas marszałka / unmarshal.
źródło
Dla tych, którzy używają
org.jvnet.jax-ws-commons:jaxws-maven-plugin
do generowania klienta z WSDL w czasie kompilacji:src/main/resources
wsdlLocation
zclasspath:
wsdlLocation
z/
Przykład:
/src/main/resources/foo/bar.wsdl
jaxws-maven-plugin
pomocą<wsdlDirectory>${basedir}/src/main/resources/foo</wsdlDirectory>
i<wsdlLocation>/foo/bar.wsdl</wsdlLocation>
źródło
1) W niektórych przypadkach tak. Jeśli WSDL zawiera takie elementy, jak zasady i takie, które kierują zachowaniem w czasie wykonywania, wówczas WSDL może być wymagany w czasie wykonywania. Artefakty nie są generowane dla rzeczy związanych z polityką i tym podobnych. Ponadto w niektórych niejasnych przypadkach RPC / Literal nie wszystkie potrzebne przestrzenie nazw są wyprowadzane w wygenerowanym kodzie (zgodnie ze specyfikacją). Zatem wsdl byłby dla nich potrzebny. Jednak niejasne przypadki.
2) Myślałem, że coś takiego zadziała. Jaka wersja CXF? To brzmi jak błąd. Możesz tam spróbować pustego łańcucha (tylko spacje). Nie jestem pewien, czy to działa, czy nie. To powiedziawszy, w swoim kodzie możesz użyć konstruktora, który pobiera adres URL WSDL i po prostu przekazuje null. WSDL nie zostanie użyty.
3) Tylko powyższe ograniczenia.
źródło
Udało mi się wygenerować
konfigurując plik pom tak, aby miał wartość null dla wsdlurl:
źródło
Czy to możliwe, że można uniknąć używania wsdl2java? Możesz od razu użyć interfejsów API CXF FrontEnd do wywołania usługi sieci Web SOAP. Jedynym haczykiem jest to, że musisz utworzyć SEI i VO po stronie klienta. Oto przykładowy kod.
Możesz zobaczyć pełny samouczek tutaj http://weblog4j.com/2012/05/01/developing-soap-web-service-using-apache-cxf/
źródło
Aktualizacja dla CXF 3.1.7
W moim przypadku umieściłem pliki WSDL w
src/main/resources
i dodałem tę ścieżkę do moich zasobów w Eclipse (Kliknij prawym przyciskiem myszy Projekt-> Ścieżka kompilacji -> Konfiguruj ścieżkę budowania ...-> Źródło [karta] -> Dodaj folder).Oto jak
pom
wygląda mój plik i jak widać NIE jestwsdlLocation
potrzebna opcja:A oto wygenerowana usługa. Jak widać, adres URL jest pobierany z ClassLoader, a nie z bezwzględnej ścieżki pliku
źródło
<configuration> <sourceRoot>${basedir}/src/main/java/</sourceRoot> <wsdlRoot>${basedir}/src/main/resources/</wsdlRoot> <includes> <include>*.wsdl</include> </includes> </configuration>
Dołączam wszystkie pliki .wsdl do ścieżki klasy, a następnie w jaki sposób mogę określić lokalizację wsdl, aby każdy wygenerowany plik .java zawierał odpowiednią ścieżkę .wsdl? Z góry dziękuję. @MazyPoważnie, najlepsza odpowiedź nie działa dla mnie. wypróbowano cxf.version 2.4.1 i 3.0.10. i generuj bezwzględną ścieżkę za każdym razem za pomocą wsdlLocation.
Moim rozwiązaniem jest użycie
wsdl2java
polecenia wapache-cxf-3.0.10\bin\
with-wsdlLocation classpath:wsdl/QueryService.wsdl
.Szczegół:
źródło
Rozwiązanie @Martin Devillers działa dobrze. Aby uzyskać kompletność, wykonaj następujące czynności:
src/main/resource
W pliku pom dodaj zarówno wsdlDirectory, jak i wsdlLocation (nie przegap / na początku wsdlLocation), jak poniżej. Podczas gdy wsdlDirectory jest używany do generowania kodu, a wsdlLocation jest używany w czasie wykonywania do tworzenia dynamicznego serwera proxy.
Następnie w swoim kodzie java (z konstruktorem no-arg):
Oto pełna część generowania kodu w pliku pom, z płynnym interfejsem API w generowanym kodzie.
źródło