IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Services Web Java Discussion :

[Axis 2] : pb appel web services avec paramètre à null


Sujet :

Services Web Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2004
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 118
    Points : 63
    Points
    63
    Par défaut [Axis 2] : pb appel web services avec paramètre à null
    Bonjour,

    j'essaye de mettre en place un service web en PHP 5+ et de pouvoir appeler ce service web avec une application Java fonctionnant avec une JRE 6.

    Débutant dans les services web, je me suis créé un petit service de test (serviceABCD).

    Voici le contenu de mon fichier WSDL de type document/literal contenant :
    • la méthode hello(String):String où le paramètre d'entrée peut-être null et doit être inférieur ou égal à 10 caractères max.
    • la méthode getDicton() : String


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions name="service" targetNamespace="serviceABCD" 
    	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    	xmlns:tns="serviceABCD" 
    	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    >
        <!-- Définition des types personnalisés -->
        <wsdl:types>
            <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="serviceABCD">
    	    <!-- Type vide -->
    	    <xsd:complexType name="empty" />
     
    	    <!-- Définition d un string nullable & <= 10 caractères -->
    	    <xsd:simpleType name="stringMax10Nillable">
    		    <xsd:restriction base="xsd:string" >
    			<xsd:maxLength value="10" />
    			<xsd:minLength value="0" />
    		    </xsd:restriction>
    	    </xsd:simpleType>
     
    	    <xsd:element name="hello" type="tns:stringMax10Nillable" nillable="true" />
    	    <xsd:element name="helloResponse" type="xsd:string" />
    	    <xsd:element name="getDicton" type="tns:empty" nillable="true" />
    	    <xsd:element name="getDictonResponse" type="xsd:string" />
            </xsd:schema>
        </wsdl:types>
     
        <!-- Abstraction de plus haut niveau des paramètres -->    
        <wsdl:message name="helloRequest" >
        	<wsdl:part name="parameters" element="tns:hello" />
        </wsdl:message>
        <wsdl:message name="helloResponse">
        	<wsdl:part name="parameters" element="tns:helloResponse"/>    
        </wsdl:message>
        <wsdl:message name="getDictonRequest">
        	<wsdl:part name="parameters" element="tns:getDicton" />
        </wsdl:message>
        <wsdl:message name="getDictonResponse">
        	<wsdl:part name="parameters" element="tns:getDictonResponse"/>
        </wsdl:message>
     
        <!-- PortType : contient des abstractions de haut niveau des opération du service web -->
        <wsdl:portType name="IServiceABCD">
        	<wsdl:operation name="hello">
        		<wsdl:documentation>Méthode hello()..</wsdl:documentation>
        		<wsdl:input message="tns:helloRequest"></wsdl:input>
        		<wsdl:output message="tns:helloResponse"></wsdl:output>
        	</wsdl:operation>
        	<wsdl:operation name="getDicton">
        		<wsdl:documentation>Méthode qui retourne un beau dicton...</wsdl:documentation>
        		<wsdl:input message="tns:getDictonRequest"></wsdl:input>
        		<wsdl:output message="tns:getDictonResponse"></wsdl:output>
        	</wsdl:operation>
        </wsdl:portType>
     
        <!-- Binding : définit le protocole à utiliser pour invoquer le service web -->
        <wsdl:binding name="BindingServiceABCD" type="tns:IServiceABCD">
        	<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
        	<wsdl:operation name="hello">
        		<soap:operation soapAction="serviceABCD/hello" />
        		<wsdl:input>
        			<soap:body use="literal" />
        		</wsdl:input>
        		<wsdl:output>
        			<soap:body use="literal" />
        		</wsdl:output>
        	</wsdl:operation>
        	<wsdl:operation name="getDicton">
        		<soap:operation soapAction="serviceABCD/getDicton" />
        		<wsdl:input>
        			<soap:body use="literal" />
        		</wsdl:input>
        		<wsdl:output>
        			<soap:body use="literal" />
        		</wsdl:output>
        	</wsdl:operation>
        </wsdl:binding>
     
        <!-- Définition du service à proprement parler -->
        <!-- Contient l URL du service -->
        <wsdl:service name="ServiceABCD">
            <wsdl:port name="PortServiceABCD" binding="tns:BindingServiceABCD">
                <soap:address location="http://localhost/ServiceABCD/index.php" />
            </wsdl:port>
        </wsdl:service>
    </wsdl:definitions>
    Voici le contenu PHP :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <?php
    	// Si on a le paramètre wsdl, on doit afficher le wsdl
    	if (isset($_GET['wsdl']))
    	{
    	     header("content-type: application/xml");
     
    	     $file = "./service.wsdl";
    	     $fp = fopen($file, "r");
    	     $fluxXml = fread($fp, filesize($file));
    	     fclose($fp);
    	     echo $fluxXml;
     
    	     exit;
    	} 
     
    	// première étape : désactiver le cache lors de la phase de test
    	ini_set("soap.wsdl_cache_enabled", "0");
     
    	// on indique au serveur à quel fichier de description il est lié
    	$serveurSOAP = new SoapServer('./service.wsdl');
     
    	// ajouter la fonction hello au serveur
    	$serveurSOAP->addFunction('hello');
     
    	// ajouter la fonction getDicton au serveur
    	$serveurSOAP->addFunction('getDicton');
     
    	// lancer le serveur
    	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    	     $serveurSOAP->handle();
    	} else {
    	     echo 'désolé, je ne comprends pas les requêtes GET, veuillez seulement utiliser POST';
    	}
     
    	function hello($nom) {
    	     return utf8_encode('Bonjour ' . $nom . ' !!!');
    	}
     
    	function getDicton() {
    	     return utf8_encode("Per Santa Luça lo jorn creis d'un saut de puça, per Nadal d'un pé de Gal");
    	}
    ?>
    J'ai utilisé l'outil wsdl2java fournit avec la librairie Axis 2 en version 1.4.1 pour générer les classes me permettant d'invoquer le service web.

    Voici ma classe de test du service :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public static void main(String[] args) throws Exception {
    	ServiceABCDStub service = new ServiceABCDStub();
     
    	Hello paramBonjourHello = new Hello();
    	StringMax10Nillable paramBonjour = new StringMax10Nillable();
    	paramBonjourHello.setHello(paramBonjour);
     
    	// 1er test avec "Virginie"		
    	paramBonjour.setStringMax10Nillable("Virginie");
    	 System.out.println(service.hello(paramBonjourHello).getHelloResponse());
     
            // 2ème test avec une chaine vide : ""
    	paramBonjour.setStringMax10Nillable("");
    		System.out.println(service.hello(paramBonjourHello).getHelloResponse());
     
            // 3ème test avec une chaine nulle 
    	paramBonjour.setStringMax10Nillable(null);
    		System.out.println(service.hello(paramBonjourHello).getHelloResponse());
     
            // 4ème test avec une chaine de caractères > 10 car. : "abcdefghijk"
    	paramBonjour.setStringMax10Nillable("abcdefghijk");
    	System.out.println(service.hello(paramBonjourHello).getHelloResponse());
    }
    En passant comme "Virginie" ou une chaine vide à la méthode hello(string):string le résultat affiché est OK.

    Si j'envoie une chaine de caractères supérieur à 10 caractères : "abcdefghijk", une RuntimeException est soulevée, ce qui est là aussi correct.

    Par contre, si j'envoie une chaine nulle à la méthode hello(string):string, j'obtiens la stack trace suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    Exception in thread "main" org.apache.axis2.AxisFault: Value cannot be null !!
    	at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
    	at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:83)
    	at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:84)
    	at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
    	at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
    	at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
    	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
    	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
    	at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:542)
    	at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:189)
    	at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
    	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:371)
    	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:209)
    	at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:448)
    	at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:401)
    	at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
    	at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
    	at fr.axis2.ServiceABCDStub.hello(ServiceABCDStub.java:1026)
    	at fr.TestServiceABCD.main(TestServiceABCD.java:26)
    Caused by: org.apache.axis2.databinding.ADBException: Value cannot be null !!
    	at fr.axis2.ServiceABCDStub$StringMax10Nillable.serialize(ServiceABCDStub.java:7775)
    	at fr.axis2.ServiceABCDStub$StringMax10Nillable.serialize(ServiceABCDStub.java:7726)
    	at fr.axis2.ServiceABCDStub$Hello.serialize(ServiceABCDStub.java:3780)
    	at fr.axis2.ServiceABCDStub$Hello.serialize(ServiceABCDStub.java:3743)
    	at fr.axis2.ServiceABCDStub$Hello$1.serialize(ServiceABCDStub.java:3731)
    	at org.apache.axis2.databinding.ADBDataSource.serialize(ADBDataSource.java:93)
    	at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.internalSerializeAndConsume(OMSourcedElementImpl.java:664)
    	at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerialize(OMElementImpl.java:918)
    	at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerializeAndConsume(OMElementImpl.java:947)
    	at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.serializeInternally(SOAPEnvelopeImpl.java:240)
    	at org.apache.axiom.soap.impl.llom.SOAPEnvelopeImpl.internalSerialize(SOAPEnvelopeImpl.java:228)
    	at org.apache.axiom.om.impl.llom.OMElementImpl.internalSerializeAndConsume(OMElementImpl.java:947)
    	at org.apache.axiom.om.impl.llom.OMNodeImpl.serializeAndConsume(OMNodeImpl.java:471)
    	at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:79)
    	... 19 more

    Dans le document WSDL, j'ai pourtant bien spécifié nullable="true" pour le paramètre d'entrée.
    Avez-vous une idée ?
    J'ai également essayé de désactiver la validation des données via un paramètre de l'outil wsdl2java mais là non plus, sans succès.

    Comment écrit-on que la valeur d'un paramètre est facultative dans un document WSDL ?
    Qu'est-ce qui ne va pas dans ma démarche ?

    Merci beaucoup de m'aider.
    F.

  2. #2
    oca
    oca est déconnecté
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    354
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2004
    Messages : 354
    Points : 421
    Points
    421
    Par défaut
    Hello,

    je suis pas complètement sûr, mais voila une piste en tout cas ...

    Tu travailles en document/literal, tu doit donc avoir un element qui va "wrapper l'opération", dans ton cas, c'est l'élément "hello"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <xsd:element name="hello" type="tns:stringMax10Nillable" nillable="true" />
    A mon avis, cet element "porteur" ne peut pas être null en document/literal (sinon on perd le lien sur l'opération...)

    Je verrais plutôt le nillable sur un element "interne" qqch du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ...
    
    <xs:element name="sayHello">
      <xs:complexType>
        <xs:sequence>
          <xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
    ...
    ...
    ...
    <wsdl:message name="sayHelloRequest">
    <wsdl:part name="parameters" element="ns0:sayHello"/>
    </wsdl:message>
    ...
    A+

Discussions similaires

  1. Web service avec paramètre type ArrayofString
    Par matrix12 dans le forum Développement de jobs
    Réponses: 4
    Dernier message: 05/03/2013, 14h51
  2. appeler web service avec projet smart device c#
    Par hichem tunis dans le forum Développement Mobile
    Réponses: 1
    Dernier message: 15/03/2012, 09h52
  3. [Web Service] Appel web service avec type complexe
    Par foujino dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 05/05/2011, 16h30
  4. [Axis] Exposer, Consommer un web services avec Eclipse
    Par kululu dans le forum Services Web
    Réponses: 0
    Dernier message: 28/04/2011, 15h28
  5. Appel Web Service avec windows authentication
    Par marylou1 dans le forum Services Web
    Réponses: 0
    Dernier message: 18/05/2010, 15h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo