2010-04-07 19 views
18

Hier ist mein CodeSo rufen Sie einen WCF-Dienst mit ksoap2 auf Android?

import org.ksoap2.*; 
import org.ksoap2.serialization.*; 
import org.ksoap2.transport.*; 

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 

public class ksop2test extends Activity { 
/** Called when the activity is first created. */ 


private static final String METHOD_NAME = "SayHello"; 
// private static final String METHOD_NAME = "HelloWorld"; 

private static final String NAMESPACE = "http://tempuri.org"; 
// private static final String NAMESPACE = "http://tempuri.org"; 

private static final String URL = "http://192.168.0.2:8080/HelloWCF/Service1.svc"; 
// private static final String URL = "http://192.168.0.2:8080/webservice1/Service1.asmx"; 

final String SOAP_ACTION = "http://tempuri.org/IService1/SayHello"; 
// final String SOAP_ACTION = "http://tempuri.org/HelloWorld"; 
TextView tv; 
StringBuilder sb; 



@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    tv = new TextView(this); 
    sb = new StringBuilder(); 
    call(); 
    tv.setText(sb.toString()); 
    setContentView(tv); 
} 

public void call() { 
    try { 

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

    request.addProperty("name", "Qing"); 

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
    SoapEnvelope.VER11); 
    envelope.dotNet = true; 
    envelope.setOutputSoapObject(request); 


    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 
    androidHttpTransport.call(SOAP_ACTION, envelope); 
    sb.append(envelope.toString() + "\n");//cannot get the xml request send 
    SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); 

    //to get the data 
    String resultData = result.toString(); 
    // 0 is the first object of data 


    sb.append(resultData + "\n"); 
    } catch (Exception e) { 
    sb.append("Error:\n" + e.getMessage() + "\n"); 
    } 

} 

} 

ich erfolgreich .asmx Dienst zugreifen kann, aber wenn ich versuche, die die virtuelle Maschine einen WCF-Dienst zu nennen: Fehler: erwartet: END_TAG {http://schemas.xmlsoap.org/soap/envelope/} Körper (Position: END_TAGhttp: //schemas.xmlsoap.org/soap/envelope/} s: Fehler> @ 1: 712 in [email protected]

Wie zu drucken, was die Anfrage sendet

Hier sind die wcf wsdl:

<wsdl:definitions name="Service1" targetNamespace="http://tempuri.org/"> 

<wsdl:types> 
    <xsd:schema targetNamespace="http://tempuri.org/Imports"> 
    <xsd:import schemaLocation="http://para-bj.para.local:8080/HelloWCF/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/> 
    <xsd:import schemaLocation="http://para-bj.para.local:8080/HelloWCF/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/> 
    </xsd:schema> 
</wsdl:types> 

<wsdl:message name="IService1_SayHello_InputMessage"> 
    <wsdl:part name="parameters" element="tns:SayHello"/> 
</wsdl:message> 

<wsdl:message name="IService1_SayHello_OutputMessage"> 
    <wsdl:part name="parameters" element="tns:SayHelloResponse"/> 
</wsdl:message> 

<wsdl:portType name="IService1"> 
    <wsdl:operation name="SayHello"> 
    <wsdl:input wsaw:Action="http://tempuri.org/IService1/SayHello" message="tns:IService1_SayHello_InputMessage"/> 
    <wsdl:output wsaw:Action="http://tempuri.org/IService1/SayHelloResponse" message="tns:IService1_SayHello_OutputMessage"/> 
    </wsdl:operation> 
</wsdl:portType> 

<wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> 

    <wsdl:operation name="SayHello"> 
    <soap:operation soapAction="http://tempuri.org/IService1/SayHello" style="document"/> 

    <wsdl:input> 
     <soap:body use="literal"/> 
    </wsdl:input> 
    <wsdl:output> 
     <soap:body use="literal"/> 
    </wsdl:output> 
    </wsdl:operation> 
</wsdl:binding> 

<wsdl:service name="Service1"> 

    <wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1"> 
    <soap:address location="http://para-bj.para.local:8080/HelloWCF/Service1.svc"/> 
    </wsdl:port> 
</wsdl:service> 

</wsdl:definitions> 

Es verwendet <xsd:schema> in Tag <wsdl:types> und die asmx verwendet <s:schema> in Tag <wsdl:types> , was ist der Unterschied?

+0

Wahrscheinlich können Sie ksoap nicht verwenden, da die davalik JVM nicht mit der Sun JVM identisch ist. Möglicherweise müssen Sie Ihren eigenen SOAP-Parser schreiben. SOAP ist wirklich zu schwer für ein mobiles Gerät, IMO. –

+0

Aber ich kann erfolgreich Daten von einem .asmx-Service erhalten – Qing

Antwort

20

schließlich habe ich es zu arbeiten, weil der Namespace ein "/" am Ende verpasst,

nach meinem Code

package cn.qing.ksop2test; 


import java.io.Writer; 

import org.ksoap2.*; 
import org.ksoap2.serialization.*; 
import org.ksoap2.transport.*; 
import org.xmlpull.v1.XmlSerializer; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Xml; 
import android.widget.TextView; 

public class ksop2test extends Activity { 
/** Called when the activity is first created. */ 


private static final String METHOD_NAME = "HelloWorldRequest"; 
// private static final String METHOD_NAME = "HelloWorld"; 

private static final String NAMESPACE = "http://tempuri.org/"; 
// private static final String NAMESPACE = "http://tempuri.org"; 

private static final String URL = "http://192.168.0.2:8080/HelloWCF/Service1.svc"; 
// private static final String URL = "http://192.168.0.2:8080/webservice1 /Service1.asmx"; 

final String SOAP_ACTION = "http://tempuri.org/IService1/HelloWorld"; 
// final String SOAP_ACTION = "http://tempuri.org/HelloWorld"; 
TextView tv; 
StringBuilder sb; 
private XmlSerializer writer; 



@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    tv = new TextView(this); 
    sb = new StringBuilder(); 
    call(); 
    tv.setText(sb.toString()); 
    setContentView(tv); 
} 

public void call() { 
    try { 

     SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

     request.addProperty("Name", "Qing"); 

     SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
       SoapEnvelope.VER11); 
     envelope.dotNet = true; 
     envelope.setOutputSoapObject(request); 


     HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 
     androidHttpTransport.call(SOAP_ACTION, envelope); 
     SoapPrimitive result = (SoapPrimitive)envelope.getResponse(); 

     //to get the data 
     String resultData = result.toString(); 
     // 0 is the first object of data 


     sb.append(resultData + "\n"); 
     } catch (Exception e) { 
     sb.append("Error:\n" + e.getMessage() + "\n"); 
     } 

    } 

} 
+4

Das ist sehr gute Demo-Code für den WCF-Webservice in Android-App zugreifen ..........., ich habe diesen Quellcode anwenden und meine Probleme lösen. .... –

+0

Die Sache für mich ist, gibt es einen anderen Antworttyp abhängig davon, was die Methode zurückgibt. Wenn es einen Rückgabewert gibt, verwenden Sie einen SoapPrimitive-Typ. Wenn es einen komplexeren Typ gibt, verwenden Sie ein SoapObject. –

+1

du hast keine ahnung wie viel das mir geholfen hat. tausend Dank. Ich habe auch diesen "/" Charakter vermisst. : D –

0

In "Theorie" sollte WCF mit grundlegenden HTTP-Bindung und asmx das gleiche funktionieren.

Es könnte etwas damit zu tun haben, wie Ihr WCF-Dienst konfiguriert ist.

Wir erhalten ein ähnliches Problem, wenn wir TransferMode Streamed auf dem Client und Buffered auf dem Server konfigurieren. Obwohl nicht sicher, ob dies in Ihrem Fall relevant ist.

1

Ich verwende So ist

private static final String SOAP_ACTION = "http://tempuri.org/IContact/GetContactCount"; 
private static final String METHOD_NAME = "GetContactCount"; 
private static final String NAMESPACE = "http://tempuri.org/"; 
private static final String URL = "http://xxx.xxx.com/Contacts/ContactsService.Contacts.svc"; 

vielleicht liegt das Problem in Ihrer SOAP-Aktion.

Auch ist die Schreibweise auf Ihrem Methodennamen korrekt dh AuthenticatdUser?

0

Dank Qing für Ihre Antwort es wirklich voll ist helfen WCF-Dienst für den Aufruf

Ich mag würde diese Berichtigung hinzufügen für immer einfache und komplexe Ausgabe von Web-Service nach dem Abbinden outputSoapObject in Umschlag, bitte korrigieren Sie mich, wenn ich bin falsch

envelope.setOutputSoapObject(requestSoapObject); 

     // if its dotnet web service then make it true 
     if (isDotNetWebService) 
      envelope.dotNet = true; 

     HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 
     androidHttpTransport.call(NAMESPACE + methodName, envelope); 

     if (useBodyIn) // use bodyIn if service method returns string/int 
         // etc 
     { 
      /* Gives output from webservice */ 
      responseSoapObject = (SoapObject) envelope.bodyIn; 
     } else // use getResponse() if service method returns objects or 
       // array 
     { 
      /* Gives output from webservice */ 
      responseSoapObject = (SoapObject) envelope.getResponse(); 
     } 
Verwandte Themen