2010-04-07 24 views
18

Aquí está mi código¿Cómo llamar a un servicio WCF usando ksoap2 en 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"); 
    } 

} 

} 

puedo acceder con éxito asmx servicio, pero cuando trato de llamar a un servicio WCF la máquina virtual dijo: error: esperada: END_TAG {} http://schemas.xmlsoap.org/soap/envelope/ cuerpo (posición: END_TAGhttp: //schemas.xmlsoap.org/soap/envelope/} s: Fault> @ 1: 712 en [email protected]

Cómo imprimir lo que la solicitud de envío

Aquí está el 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> 

Utiliza <xsd:schema> en la etiqueta <wsdl:types> y la asmx utiliza <s:schema> en la etiqueta <wsdl:types> cuál es la diferencia?

+0

Probablemente no pueda usar ksoap, ya que la JVM davalik no es lo mismo que la Sun JVM. Es posible que necesite escribir su propio analizador SOAP. SOAP es realmente demasiado pesado para un dispositivo móvil, IMO. –

+0

Pero puedo obtener datos de un servicio .asmx con éxito – Qing

Respuesta

20

fin llegué a trabajar debido a que el espacio de nombres se perdió una "/" al final,

siguiente es mi código

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

Este es un código de demostración muy bueno para acceder al servicio web WCF en la aplicación de Android ............ He aplicado este código fuente y he resuelto mis problemas. .... –

+0

Lo que pasa es que hay un tipo de respuesta diferente dependiendo de lo que devuelva el método. Si hay un valor de retorno, usa un tipo SoapPrimitive; si hay un tipo más complejo, usa un SoapObject. –

+1

no tienes idea de cuánto me ha ayudado esto. montones de gracias. Me perdí ese personaje "/" también. :RE –

0

En "teoría" wcf con enlace http básico y asmx debería funcionar igual.

Podría ser algo relacionado con la configuración de su servicio WCF.

Tenemos un problema similar si configuramos TransferMode Stream en el cliente y Buffered en el servidor. Aunque no estoy seguro de si esto es relevante en su caso.

1

estoy usando

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

Así tal vez el problema esté en tu acción SOAP.

También está la ortografía en su nombre de método correcto, es decir, AuthenticatdUser?

0

Gracias Qing por su respuesta que realmente ayude completo para llamar al servicio WCF

me gustaría añadir esta rectificación para conseguir la salida simple y compleja a partir servicio web después de establecer outputSoapObject en el sobre, por favor me corrija si me incorrecto

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(); 
     } 
Cuestiones relacionadas