2012-04-04 2 views
2

Ksoap2 라이브러리를 사용하는 Android 장치에서 WCF .Net 웹 서비스에 연결하려고합니다. 모든 것이 잘 작동하고, 지금까지 복잡한 문제를 보내고받을 수있었습니다 (많은 문제 해결 후). 그러나, 이제 nullable 형식의 문제가 발생합니다. 서버 측에서는 보내려는 많은 속성을 null 값으로 설정할 수 있습니다. 안드로이드 측에서 null로 보내려고하면 ksoap이 nil = true 대신 null = true를 설정하기 때문에 deserialization 오류가 발생합니다. 다음은 Android 클라이언트의 현재 XML뿐만 아니라 테스트 드라이버의 SOAP XML 작동 일부입니다.Android ksoap2 nullable type

작업 테스트 드라이버 XML

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
<s:Body> 
    <AddNullables xmlns="http://TJIsGhey/Tester"> 
     <NumbersToAdd xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
      <Input1>7</Input1> 
      <Input2 i:nil="true" /> 
     </NumbersToAdd> 
    </AddNullables> 
</s:Body> 
</s:Envelope> 

안드로이드 클라이언트 XML 여기

<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/"> 
    <v:Header /> 
    <v:Body> 
     <AddNullables xmlns="http://TJIsGhey/Tester" id="o0" c:root="1"> 
      <NumbersToAdd i:type="n0:NullablesIn" xmlns:n0="http://TJIsGhey/Tester"> 
       <Input1 i:type="d:int">6</Input1> 
       <Input2 i:null="true" /> 
      </NumbersToAdd> 
     </AddNullables> 
    </v:Body> 
</v:Envelope> 

내가 받고있어 오류 메시지는 다음과 같습니다 유형 테스터의 객체를 직렬화 복원 오류가 발생했습니다

.NullablesIn. ''값을 'Int32'유형으로 구문 분석 할 수 없습니다.

도움이 될 것입니다.

답변

2

나는 동일한 문제가있었습니다. Ksoap2 소스 코드를 뚫고 문제를 발견했습니다. SoapSerializationEnvelope에서 VER12를 사용하는 것이 가장 쉬운 첫 번째 솔루션과 두 가지 가능한 솔루션이 있습니다. Ksoap2는 VER12 이상부터 nil 속성 만 사용하므로 그러나이 변경 사항으로 인해 다른 옵션이 적용될 수 있습니다. SoapSerializationEnvelope를 상속하고이 클래스의 writeProperty 메서드를 재정의합니다. 그래서 :

public class ExtendedSoapSerializationEnvelope extends 
    SoapSerializationEnvelope { 

public ExtendedSoapSerializationEnvelope(int version) { 
    super(version); 
} 

@Override 
protected void writeProperty(XmlSerializer writer, Object obj, 
     PropertyInfo type) throws IOException { 
    if (obj == null) { 

     if (!(obj instanceof SoapObject)) { 
      // assuming object implements KvmSerializable or other type of 
      // Serialization interface 
      writer.attribute(xsi, version >= VER11 ? "nil" : "null", "true"); 

     } else { 
      // assuming SoapObject being used with VER12 and up 
      writer.attribute(xsi, version >= VER12 ? "nil" : "null", "true"); 
     } 
     return; 
    } 
    super.writeProperty(writer, obj, type); 
}} 

당신이 당신의 웹 서비스는 항상 altogther이 검사를 건너 뛸 수 nil을 작동 그냥 사용하는 것이 알고있는 경우 :

@Override 
protected void writeProperty(XmlSerializer writer, Object obj, 
     PropertyInfo type) throws IOException { 
    if (obj == null) { 
     writer.attribute(xsi, "nil", "true"); 
     return; 
    } 

    super.writeProperty(writer, obj, type); 

} 
1

해결 방법은 다음과 같이 매개 변수 skipNullProperties를 사용하여이 "<element type>" 무시입니다 :

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
envelope.skipNullProperties=true; 
0

문제는 해결되었다

import android.os.AsyncTask; 
 
import android.support.v7.app.AppCompatActivity; 
 
import android.os.Bundle; 
 
import android.widget.TextView; 
 
import org.ksoap2.SoapEnvelope; 
 
import org.ksoap2.serialization.SoapObject; 
 
import org.ksoap2.serialization.SoapSerializationEnvelope; 
 
import org.ksoap2.transport.HttpsTransportSE; 
 
import java.net.URISyntaxException; 
 

 
public class MainActivity extends AppCompatActivity { 
 
    private static final String URL = "https://services.rs.ge/WayBillService/WayBillService.asmx?WSDL"; 
 

 
    TextView tv; 
 

 
    @Override 
 
    public void onCreate(Bundle savedInstanceState) { 
 
     super.onCreate(savedInstanceState); 
 
     tv = new TextView(this); 
 
     String[] params = new String[]{"save_waybill","s22:12345678910","123456"}; 
 
     new MyAsyncTasc().execute(params); 
 
     setContentView(tv); 
 
    } 
 

 
    class MyAsyncTasc extends AsyncTask<String,Void,String> { 
 
     @Override 
 
     protected String doInBackground(String... params) { 
 
      String SOAP_ACTION="http://tempuri.org/"+params[0]; 
 
      int timeOut = 60000; 
 
      SoapSerializationEnvelope __envelope=new SoapSerializationEnvelope(SoapEnvelope.VER11); 
 
      SoapObject request = new SoapObject("http://tempuri.org/", params[0]); 
 
      __envelope.dotNet = true; 
 
      __envelope.setOutputSoapObject(request); 
 
      request.addProperty("su", params[1]); 
 
      request.addProperty("sp", params[2]); 
 

 
      //------------------ SoapObject 
 
      SoapObject waybill1 = new SoapObject("", "WAYBILL"); 
 
      SoapObject goods1 = new SoapObject("", "GOODS"); 
 
      SoapObject good_list1 = new SoapObject("", "GOODS_LIST"); 
 
      waybill1.addProperty("SELER_UN_ID", 1149251); 
 
      waybill1.addProperty("ID", 0); 
 
      waybill1.addProperty("TYPE", 1); 
 
      waybill1.addProperty("STATUS", 1); 
 
      waybill1.addProperty("START_ADDRESS", "START_ADDRESS"); 
 
      waybill1.addProperty("END_ADDRESS", "END_ADDRESS"); 
 
      waybill1.addProperty("DRIVER_TIN", "61007004242"); 
 
      waybill1.addProperty("CAR_NUMBER", "AAA000"); 
 
      waybill1.addProperty("CHEK_DRIVER_TIN", 1); 
 
      waybill1.addProperty("TRANSPORT_COAST", 0); 
 
      waybill1.addProperty("TRAN_COST_PAYER", 2); 
 
      waybill1.addProperty("TRANS_ID", 1); 
 

 
      goods1.addProperty("ID", 0); 
 
      goods1.addProperty("W_NAME", "W_NAME"); 
 
      goods1.addProperty("UNIT_ID", 1); 
 
      goods1.addProperty("QUANTITY", 2); 
 
      goods1.addProperty("PRICE", 1); 
 
      goods1.addProperty("AMOUNT", 2); 
 
      goods1.addProperty("BAR_CODE", "1"); 
 

 
      good_list1.addProperty("GOODS", goods1); 
 

 
      goods1 = new SoapObject("", "GOODS"); 
 
      goods1.addProperty("ID", 0); 
 
      goods1.addProperty("W_NAME", "W_NAME2"); 
 
      goods1.addProperty("UNIT_ID", 1); 
 
      goods1.addProperty("QUANTITY", 4); 
 
      goods1.addProperty("PRICE", 1); 
 
      goods1.addProperty("AMOUNT",4); 
 
      goods1.addProperty("BAR_CODE", "2"); 
 

 
      good_list1.addProperty("GOODS", goods1); 
 

 
      waybill1.addProperty("GOODS_LIST", good_list1); 
 
      SoapObject wib_send = new SoapObject("", "waybill"); 
 
      wib_send.addProperty("WAYBILL", waybill1); 
 
      request.addProperty("waybill", wib_send); 
 

 
      java.net.URI uri = null; 
 
      try { 
 
       uri = new java.net.URI(URL); 
 
      } catch (URISyntaxException e) { 
 
       e.printStackTrace(); 
 
      } 
 
      int port=uri.getPort()>0?uri.getPort():443; 
 
      HttpsTransportSE httpTransport= new HttpsTransportSE(uri.getHost(), port, uri.getPath(), timeOut); 
 
      httpTransport.debug = true; 
 
      try { 
 
       httpTransport.call(SOAP_ACTION, __envelope); 
 
       SoapObject resultRequestSOAP = (SoapObject) __envelope.bodyIn; 
 
       return resultRequestSOAP.toString(); 
 
      } catch(Exception exp){ 
 
       return "Error"; 
 
      } 
 
     } 
 
     @Override 
 
     protected void onPostExecute(final String result) { 
 
      tv.setText(result); 
 
     } 
 
    } 
 
}