2012-02-20 6 views
0
<?xml version="1.0" encoding="UTF-8"?> 
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> 
    <S:Header/> 
    <S:Body> 
     <ns2:FReadStatus xmlns:ns2="http://poweb13/"> 
      <arg0>000D6F0000</arg0> 
     </ns2:FReadStatus> 
    </S:Body> 
</S:Envelope> 

Я работаю над проектом Android, который я хочу использовать для JAX-WS. Услуги сделаны кем-то еще, так что я не могу изменить что-либо из them.I хочу отправить сообщение выше SOAP с этим написанным кодом, но единственным, что я получать, когда их называют это java.lang.NullPointerExceptionКак создать запрос SOAP через ksoap2

private static final String NAMESPACE = "http://poweb13/"; 
private static final String URL = "http://smart.gr:8080/aWESoME/SmartPlugService?wsdl"; 
private static final String SOAP_ACTION = "SmartPlugService"; 
private static final String METHOD_NAME = "FReadStatus"; 
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 
PropertyInfo p1 = new PropertyInfo(); 
p1.setName("MAC"); 
p1.setValue("000D6F0000"); 
p1.setType(myDevice.getmac().toString().getClass()); 
request.addProperty(p1); 
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
envelope.setOutputSoapObject(request); 
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); 
try {   
    androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");     
    androidHttpTransport.call(SOAP_ACTION, envelope); 
    SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn; 
    String result=resultsRequestSOAP.getProperty("return").toString(); 
    Log.i("info","Received :" + result); 
} catch (java.lang.ClassCastException e){ 
    SoapFault fault=(SoapFault)envelope.bodyIn; 
    Log.e("error","Received :" + fault.getMessage().toString()); 
    Log.e("error","Received :" + fault.getLocalizedMessage().toString()); 
    StackTraceElement[] st=fault.getStackTrace(); 
    for(int i=0;i<st.length;i++){ 
     Log.e("error","Received :" +st[i]); 
    } 
} catch (Exception e) { 
    Log.e("error","smthing went wrong!!"); 
    e.printStackTrace(); 
} 

Я думаю, что он даже не создает XML-документ, но я не знаю, как его проверить. Я попытался создать XmlSerializer для размещения данных для создания xml, но также получаю исключение NullPointerException. Так может ли кто-нибудь помочь мне о том, как закодировать вышеуказанный запрос? вот некоторые части файла WSDL

<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://poweb13/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://poweb13/" name="SmartPlugService"> 
<types> 
<xsd:schema> 
<xsd:import namespace="http://poweb13/" schemaLocation="http://smart.gr:8080/aWESoME/SmartPlugService?xsd=1"/> 
</xsd:schema> 
</types> 


<message name="FReadStatus"> 
<part name="parameters" element="tns:FReadStatus"/> 
</message> 
... 
<portType name="SmartPlugService"> 
<operation name="FReadStatus"> 
... 
<input wsam:Action="http://poweb13/SmartPlugService/FReadStatusRequest" message="tns:FReadStatus"/> 
<output wsam:Action="http://poweb13/SmartPlugService/FReadStatusResponse" message="tns:FReadStatusResponse"/> 
<fault message="tns:InvalidDeviceAddressException" name="InvalidDeviceAddressException" wsam:Action="http://poweb13/SmartPlugService/FReadStatus/Fault/InvalidDeviceAddressException"/> 
<fault message="tns:InternalServiceException" name="InternalServiceException" wsam:Action="http://poweb13/SmartPlugService/FReadStatus/Fault/InternalServiceException"/> 
... 
</operation> 
</portType> 
<binding name="SmartPlugServicePortBinding" type="tns:SmartPlugService"> 
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> 
... 
<operation name="FReadStatus"> 
<soap:operation soapAction=""/> 
<input> 
<soap:body use="literal"/> 
</input> 
<output> 
<soap:body use="literal"/> 
</output> 
<fault name="InvalidDeviceAddressException"> 
<soap:fault name="InvalidDeviceAddressException" use="literal"/> 
</fault> 
<fault name="InternalServiceException"> 
<soap:fault name="InternalServiceException" use="literal"/> 
</fault> 
</operation> 
... 
</binding> 

Некоторые части XSD файл

<xs:schema xmlns:tns="http://poweb13/" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://poweb13/"> 
<xs:element name="FReadStatus" type="tns:FReadStatus"/> 
<xs:complexType name="FReadStatus"> 
<xs:sequence> 
<xs:element name="arg0" type="xs:string" minOccurs="0"/> 
</xs:sequence> 
</xs:complexType> 

я должен иметь ответ SOAP вроде этого:

SOAP Response 

<?xml version="1.0" encoding="UTF-8"?> 
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> 
    <S:Body> 
     <ns2:FReadStatusResponse xmlns:ns2="http://poweb13/"> 
      <return>1</return> 
     </ns2:FReadStatusResponse> 
    </S:Body> 
</S:Envelope> 

ответ

2

Ok поэтому у вас есть функция FReadStatus:

<message name="FReadStatus"> 
    <part name="parameters" element="tns:FReadStatus"/> 
</message> 

, который имеет элемент FReadStatusсложный тип (т.е. объект, который является классом, найденным на сервере).
Этот сложный тип имеет атрибут arg0 типа String. Его определение:

<xs:complexType name="FReadStatus"> 
    <xs:sequence> 
    <xs:element name="arg0" type="xs:string" minOccurs="0"/> 
    </xs:sequence> 
</xs:complexType> 

Так что вам нужно будет создать локальный класс, который реализует kvmSerializable для отображения этого сложного типа в соответствующий класс на сервере, так что вы будете делать:

public class FReadStatus implements KvmSerializable { 

String mac; 

@Override 
public Object getProperty(int arg0) { 
switch (arg0){ 
    case 0: 
     return mac; 
    default: 
     return null; 
     } 
} 

@Override 
public int getPropertyCount() { 
    return 1;//because you have 1 parameter 
} 

@Override 
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) { 
switch(arg0) 
{ 

    case 0: 
     arg2.type = PropertyInfo.STRING_CLASS;//because its type is string 
     arg2.name = "arg0"; 
     break; 
    default:break; 
} 

} 

@Override 
public void setProperty(int arg0, Object arg1) { 
switch(arg0) 
{ 
    case 0: 
     mac= (String)arg1; 
     break; 
    default: 
     break; 
} 
} 

Теперь, когда у вас есть класс, вы будете делать следующее в коде вы имели:

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

    PropertyInfo pi = new PropertyInfo(); 
    pi.setName("arg0"); 
    pi.setValue("000D6F0000"); 
    pi.setType(FReadStatus .class); 
    request.addProperty(pi); 

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

    //Now you have to add mapping to map the local class created, to the one on the server 
    envelope.addMapping(NAMESPACE , FReadStatus.class.getSimpleName(), FReadStatus .class); 

    // Add marshalling (this one might not be necessary, but ill just add it) 
    Marshal floatMarshal = new MarshalFloat(); 
    floatMarshal.register(envelope); 

    AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);//AndroidHttpTransport INSTEAD OF HttpTransportSE 

    androidHttpTransport.debug = true;//NEW ADDED 
    try {   

     androidHttpTransport.call(SOAP_ACTION, envelope); 

     //Important Outputs to check how the request/Response looks like.. Check them in Logcat to find these outputs 
     System.out.println("requestDump is :"+androidHttpTransport.requestDump); 
     System.out.println("responseDump is :"+androidHttpTransport.responseDump); 
     System.out.println("response"+envelope.getResponse()); 

    } catch (Exception e){} 

Позвольте мне знать вес бывает. Вы должны использовать Logcat проверить requestDump и responseDump

UPDATE: отвечая на ваш вопрос о UnknowHostException
возможные причины и решения

  • Проверьте, если в вашем AndroidManifest.xml у вас есть:

    <uses-permission android:name="android.permission.INTERNET" /> 
    
  • Если вы используете эмулятор, как указано в этом link

  • Если вы находитесь за прокси делать:

    System.setProperty("http.proxyHost", "my.proxyhost.com"); 
    System.setProperty("http.proxyPort", "1234"); 
    
  • Вам может понадобиться использовать прогрев СНД, проверьте этот link

Смежные вопросы