Lorsque je génère un client de service Web en utilisant wsdl2java à partir de CXF (qui génère quelque chose de similaire à wsimport), via maven, mes services commencent par des codes comme celui-ci:
@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;
}
Le chemin absolu codé en dur est vraiment nul. La classe générée ne fonctionnera sur aucun autre ordinateur que le mien.
La première idée est de mettre le fichier WSDL (plus tout ce qu'il importe, les autres WSDL et XSD) quelque part dans un fichier jar et le classpath. Mais nous voulons éviter cela. Puisque tout cela a été généré par CXF et JAXB basés sur les WSDL et XSD, nous ne voyons aucun intérêt à avoir besoin de connaître le WSDL au moment de l'exécution.
L'attribut wsdlLocation est destiné à remplacer l'emplacement WSDL (au moins c'est ce que j'ai lu quelque part), et sa valeur par défaut est "". Puisque nous utilisons maven, nous avons essayé d'inclure <wsdlLocation></wsdlLocation>
dans la configuration de CXF pour essayer de forcer le générateur de source à laisser le wsdlLocation vide. Cependant, cela le fait simplement ignorer la balise XML car elle est vide. Nous avons fait un hack vraiment laid et honteux, en utilisant <wsdlLocation>" + "</wsdlLocation>
.
Cela change aussi d'autres endroits:
@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;
}
Donc, mes questions sont:
Avons-nous vraiment besoin d'un emplacement WSDL même si toutes les classes ont été générées par CXF et JAXB? Si oui, pourquoi?
Si nous n'avons pas vraiment besoin de l'emplacement WSDL, quel est le moyen approprié et propre pour empêcher CXF de le générer et de l'éviter complètement?
Quels effets secondaires pourrions-nous avoir avec ce hack? Nous ne pouvons toujours pas tester cela pour voir ce qui se passe, donc si quelqu'un pouvait dire à l'avance, ce serait bien.
classpath:
in JAX Maven au lieu de CXF, omettez-le dans la<wsdlLocation...
ligne.Nous utilisons
En d'autres termes, utilisez un chemin relatif au chemin de classe.
Je crois que le WSDL peut être nécessaire au moment de l'exécution pour la validation des messages pendant le marshal / unmarshal.
la source
Pour ceux qui utilisent
org.jvnet.jax-ws-commons:jaxws-maven-plugin
pour générer un client à partir de WSDL au moment de la construction:src/main/resources
wsdlLocation
avecclasspath:
wsdlLocation
avec/
Exemple:
/src/main/resources/foo/bar.wsdl
jaxws-maven-plugin
avec<wsdlDirectory>${basedir}/src/main/resources/foo</wsdlDirectory>
et<wsdlLocation>/foo/bar.wsdl</wsdlLocation>
la source
1) Dans certains cas, oui. Si le WSDL contient des éléments tels que des stratégies et de ce type qui dirigent le comportement d'exécution, alors le WSDL peut être requis lors de l'exécution. Les artefacts ne sont pas générés pour des éléments liés aux politiques et autres. De plus, dans certains cas obscurs de RPC / Littéral, tous les espaces de noms nécessaires ne sont pas affichés dans le code généré (par spécification). Ainsi, le wsdl leur serait nécessaire. Des cas obscurs cependant.
2) Je pensais que quelque chose comme ça fonctionnerait. Quelle version de CXF? Cela ressemble à un bug. Vous pouvez essayer une chaîne vide ici (juste des espaces). Je ne sais pas si cela fonctionne ou non. Cela dit, dans votre code, vous pouvez utiliser le constructeur qui prend l'URL WSDL et ne passe que null. Le wsdl ne serait pas utilisé.
3) Juste les limitations ci-dessus.
la source
J'ai pu générer
en configurant le fichier pom pour avoir un null pour wsdlurl:
la source
Est-il possible que vous puissiez éviter d'utiliser wsdl2java? Vous pouvez immédiatement utiliser les API CXF FrontEnd pour appeler votre Webservice SOAP. Le seul hic, c'est que vous devez créer votre SEI et vos VO du côté de votre client. Voici un exemple de code.
Vous pouvez voir le tutoriel complet ici http://weblog4j.com/2012/05/01/developing-soap-web-service-using-apache-cxf/
la source
Mise à jour pour CXF 3.1.7
Dans mon cas, j'ai mis les fichiers WSDL
src/main/resources
et ajouté ce chemin à mes Srouces dans Eclipse (clic droit sur Projet-> Chemin de construction -> Configurer le chemin de construction ...-> Source [Tab] -> Ajouter un dossier).Voici à quoi
pom
ressemble mon fichier et comme on peut le voir, aucunewsdlLocation
option n'est nécessaire:Et voici le service généré. Comme on peut le voir, l'URL provient de ClassLoader et non du chemin d'accès absolu au fichier
la source
<configuration> <sourceRoot>${basedir}/src/main/java/</sourceRoot> <wsdlRoot>${basedir}/src/main/resources/</wsdlRoot> <includes> <include>*.wsdl</include> </includes> </configuration>
J'inclus tous les fichiers .wsdl dans le chemin de classe, alors comment puis-je spécifier l'emplacement wsdl afin que chaque fichier .java généré puisse contenir le chemin .wsdl respectif? Merci d'avance. @MazySérieusement, la meilleure réponse ne fonctionne pas pour moi. essayé cxf.version 2.4.1 et 3.0.10. et générer un chemin absolu avec wsdlLocation à chaque fois.
Ma solution est d'utiliser la
wsdl2java
commande dans leapache-cxf-3.0.10\bin\
avec-wsdlLocation classpath:wsdl/QueryService.wsdl
.Détail:
la source
La solution @Martin Devillers fonctionne très bien. Pour être complet, fournissez les étapes ci-dessous:
src/main/resource
Dans le fichier pom, ajoutez à la fois wsdlDirectory et wsdlLocation (ne manquez pas / au début de wsdlLocation), comme ci-dessous. Alors que wsdlDirectory est utilisé pour générer du code et wsdlLocation est utilisé lors de l'exécution pour créer un proxy dynamique.
Puis dans votre code java (avec constructeur no-arg):
Voici la partie de génération de code complète dans le fichier pom, avec une API fluide dans le code généré.
la source