46 votes

JAX-WS Chargement de WSDL depuis un bocal

Je suis en train d'écrire un gros client qui fait appel à un service SOAP pour certaines fonctions (rapport de bug etc.)

J'ai JAX-WS fonctionne très bien, mais par défaut (dans netbeans au moins), il va chercher le fichier WSDL à partir du serveur distant à chaque fois que le service est initialisé. J'espère que cela contribue à fournir un certain soutien de versioning, etc., mais ce n'est pas ce que je veux.

J'ai ajouté l' wsdllocation arg à wsimport à point, les classes générées à une ressource locale. L'extrait suivant est l'URL de chargement de la ressource à partir de WSDL ApplicationService.java.

baseUrl = net.example.ApplicationService.class.getResource(".");
url = new URL(baseUrl, "service.wsdl");

Je suis assez sûr qu'devrait pas avoir de problèmes pointant vers une ressource stockée à l'intérieur d'un pot dans le net/exemple/de ressources, et le pot lui-même est construit comme prévu. Cependant, le service ne sera pas chargé... en particulier, je reçois un NullPointerException quand je l'appelle ApplicationService.getPort();

Est-ce possible? ou tout simplement un wild goose chase?

51voto

DavidValeri Points 1494

Oui, c'est très certainement possible comme je l'ai fait lors de la création de clients à travers javax.xml.ws.EndpointReference, WS-UNE classe connexe. J'ai ajouté un classpath de référence pour le WSDL pour le WS-UN EndPointReference et le Métro de la mise en œuvre de JAX-WS chargé c'est très bien. Si le chargement du fichier WSDL à partir du WS-UN EndPointReference ou à partir d'un fichier ou une URL http, votre JAX-WS mise en œuvre devrait utiliser le même WSDL code d'analyse que tout ce que vous faites de la résolution d'Url.

La meilleure approche pour vous, c'est probablement de faire quelque chose comme ce qui suit:

URL wsdlUrl = MyClass.class.getResource(
            "/class/path/to/wsdl/yourWSDL.wsdl");

Service yourService= Service.create(
            wsdlUrl,
            ...);

Où [ ... ] représente le Nom d'un fichier WSDL du service à l'intérieur de votre WSDL. Maintenant, la chose importante à retenir est que votre WSDL doit être complet et valide. Cela signifie que si votre WSDL importations XSD fichiers ou d'autres fichiers wsdl, l'Url doit être correcte. Si vous avez inclus votre importation WSDL et XSDs dans le même POT que le fichier WSDL, vous devez utiliser des Url relatives pour les importations et les garder tous vos importations dans le même fichier JAR. Le POT de gestionnaire d'URL ne permet pas de traiter les Url relatives par rapport à l'égard du classpath, mais plutôt à une relative dans le fichier JAR si vous ne pouvez pas avoir les importations dans votre WSDL qui courent à travers les Pots à moins que vous mettre en œuvre une URL personnalisée de gestionnaire et votre propre préfixe de faire de chemin de classe basée sur la résolution des importations. Si votre WSDL importations de ressources externes, c'est OK, mais vous vous connectez-vous pour des questions d'entretien si ces ressources ne jamais se déplacer. Même en utilisant une copie statique du WSDL à partir de votre classpath est contraire à l'esprit de WSDL, Web services, et JAX-WS, mais il y a des moments où il est nécessaire.

Enfin, si vous incorporez un statique WSDL, je vous suggère de faire au moins le point de terminaison de service configurable pour les tests et le déploiement des fins. Le code de reconfigurer le point de terminaison de votre client de service Web est comme suit:

  YourClientInterface client = yourService.getPort(
            new QName("...", "..."),
            YourClientInterface.class);
  BindingProvider bp = (BindingProvider) client;
  bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
                "http://localhost:8080/yourServiceEndpoint");

17voto

Adam Gent Points 15055

Au moins pour les dernières JAX-WS vous n'avez pas besoin de faire un schéma des catalogues ou des programmes wsdl paramètre d'emplacement SI vous mettez le WSDL dans le bol et réglez ensuite wsimport wsdlLocation de la relative ressources chemin d'accès du fichier WSDL dans le POT. C'est JAX-WS utilise Java builtin Class.getResource de charger le fichier WSDL.

Si votre utilisation de Maven c'est quelque chose comme:

  <plugin>
    <groupId>org.jvnet.jax-ws-commons</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.3</version>
    <executions>
      <execution>
        <goals>
          <goal>wsimport</goal>
        </goals>
        <!-- Following configuration will invoke wsimport once for each wsdl. -->
        <configuration>
            <!--- VERY IMPORTANT THAT THE PATH START WITH '/' -->
    <wsdlLocation>/com/adamgent/ws/blah.wsdl</wsdlLocation>
    <wsdlDirectory>${basedir}/src/main/resources/com/adamgent/ws</wsdlDirectory>
    <wsdlFiles><wsdlFile>blah.wsdl</wsdlFile></wsdlFiles>
       </configuration>
      </execution>
    </executions>
  </plugin>

Pour l'exemple ci-dessus, vous devez mettre le fichier WSDL à l'aide de Maven de présentation de projet ici, src/main/resources/com/adamgent/ws.

Assurez-vous que le WSDL obtient dans le POT pour Maven comme:

<build>
      <resources>
        <resource>
          <directory>src/main/resources</directory>
        </resource>
      </resources> ....

Maintenant, votre wsimport code généré et WSDL sont dans une JARRE. Pour utiliser le service, vous n'avez pas à régler l'emplacement WSDL et est aussi simple que:

BlahService myService = new BlayService_Service().getBlahServicePort();

Il doit être facile à carte à la FOURMI wsimport.

6voto

weiresr Points 441

Peut-être un peu en retard, mais j'ai trouvé un assez simple solution qui a fonctionné pour résoudre ce problème, mais cela a entraîné un changement dans le code généré de la classe de Service:

Si la ligne suivante dans la classe de Service

baseUrl = net.example.ApplicationService.class.getResource(".");

est modifié pour

baseUrl = net.example.ApplicationService.class.getResource("");

il fonctionne très bien, même avec un WSDL qui est emballé dans un BOCAL. Pas sûr de savoir exactement censé comportement de getResource() dans ce cas, mais je n'ai pas de problèmes avec cette approche jusqu'à présent, sur plusieurs systèmes d'exploitation et versions de Java.

3voto

thorty Points 31

Une autre réponse est à Uste le nouveau service (wsdllocation, servicename); pour obtenir l'objet de service.

C'est ainsi que j'ai résolu le problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X