2010-04-07 14 views
18

Oto mój kodJak wywołać usługę WCF za pomocą ksoap2 na Androida?

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"); 
    } 

} 

} 

można pomyślnie przejść .asmx usługę, ale gdy próbuję zadzwonić usług wcf maszyna wirtualna powiedział: Błąd: spodziewanych: END_TAG {http://schemas.xmlsoap.org/soap/envelope/} ciała (pozycja: END_TAGhttp: //schemas.xmlsoap.org/soap/envelope/} s: Błąd> @ 1: 712 w [email protected]

Jak drukować co wniosek wysłać

Tu jest 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> 

Wykorzystuje <xsd:schema> w tagu <wsdl:types> i ASMX wykorzystuje <s:schema> w tagu <wsdl:types> co za różnica?

+0

Prawdopodobnie nie można używać ksoap, ponieważ davalik JVM nie jest tym samym, co JVM Sun. Może być konieczne napisanie własnego parsera SOAP. SOAP jest naprawdę zbyt ciężki dla urządzenia mobilnego, IMO. –

+0

Ale mogę z powodzeniem pobierać dane z usługi .asmx – Qing

Odpowiedz

20

wreszcie dostałem go do pracy ponieważ nazw zmarnował "/" w końcu

Oto mój kod

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

To jest bardzo dobry kod demo dostępu do usługi WCF w aplikacji na Androida ..........., zastosowałem ten kod źródłowy i rozwiązałem moje problemy. .... –

+0

Rzeczą dla mnie jest inny typ odpowiedzi w zależności od tego, co zwraca metoda. Jeśli istnieje jedna zwracana wartość, należy użyć typu SoapPrimitive, jeśli istnieje bardziej złożony typ, należy użyć obiektu SoapObject. –

+1

nie masz pojęcia, jak bardzo mi to pomogło. dzięki hałdom. Tęskniłem również za tą postacią "/". :RE –

0

W "teorii" wcf z podstawowym wiązaniem http i asmx powinno działać tak samo.

Może to mieć związek z konfiguracją usługi WCF.

Otrzymujemy podobny problem, jeśli skonfigurujemy TransferMode Streamed na kliencie i Buforowany na serwerze. Chociaż nie jestem pewien, czy jest to istotne w twoim przypadku.

1

Używam

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"; 

So być może problem dotyczy akcji SOAP.

Czy poprawna jest również pisownia nazwy metody, np. AuthenticatdUser?

0

Dzięki Qing za odpowiedź to naprawdę pomaga w całości za wywołanie usługi WCF

Chciałbym dodać ten sprostowania uzyskania prostego i złożonego wyjście z usługi internetowej po ustawieniu outputSoapObject w kopercie, proszę mnie poprawić, jeśli jestem źle

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(); 
     } 
Powiązane problemy