Не получать вложенные узлы XML от веб-службы SOAP с использованием ksoap2 - PullRequest
0 голосов
/ 08 февраля 2012

чао всем, Я становлюсь глупым по этому вопросу. Я надеюсь, что кто-то может помочь мне!! Я искал в Интернете решение, но когда-либо обнаружил, что не работает для меня. Это сценарий: Я пытаюсь сделать запрос к .net ws. Запрос прост, но ответом является вложенная двухуровневая XML-структура, которая выглядит следующим образом:

<soap:Body>
    <ProgettoResponse xmlns="http://tempuri.org/">
      <ProgettoResult xmlns="">
        <Success>boolean</Success>
        <Message>string</Message>
        <Progetto>
          <Titolo>string</Titolo>
          <Descrizione>string</Descrizione>
        </Progetto>
      </ProgettoResult>
    </ProgettoResponse>
  </soap:Body>

но ответ, который я получаю от WS, всегда таков: anyType {Success = true; Сообщение = OK; Progetto = anyType {};}

эта ситуация подтверждается logcat

Узел всегда пуст. Я уверен, что WS, вызываемый с теми же параметрами, отправляет полную структуру (через веб-приложение и через i-phone рекламного приложения).

Я использую ksoap2-android-Assembly-2.6.0-JAR-с-зависимостями в среде Android 2.1 / 2.2.

Это класс, который я использую для вызова ws:

package feronia.culturando.android;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;


public class webService 
{
    public final String SOAP_ACTION = "http://tempuri.org/Progetto";
public  final String METHOD_NAME = "Progetto"; 
public  final String NAMESPACE = "http://tempuri.org/";
public  final String URL = "http://www.feronia.it/intra/webservice/wsCulturando.asmx";

    public webService() 
    { 
    }

    public String Call(String a,int b)
    {
            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
            PropertyInfo pi=new PropertyInfo();
                            pi.setName("a");
                    pi.setValue(a);
                    pi.setType(String.class);
                    request.addProperty(pi);
                    pi=new PropertyInfo();
                    pi.setName("b");
                    pi.setValue(b);
                    pi.setType(Integer.class);
                    request.addProperty(pi);

            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
            SoapEnvelope.VER11);

            envelope.dotNet = true;         
            envelope.setOutputSoapObject(request);

            envelope.addMapping(NAMESPACE, "ProgettoResult", new ProgettoResult().getClass());
            envelope.addMapping(NAMESPACE, "Progetto", new Progetto().getClass());


            HttpTransportSE httpTransport = new HttpTransportSE(URL);
            SoapObject response=null;

            String totalCount = "";
            try
            {
                    httpTransport.call(SOAP_ACTION, envelope);

                    response = (SoapObject)envelope.getResponse();
                    //totalCount = response.getPropertyAsString("Progetto").toString();     
                    //totalCount = response.toString();
                    //Progetto prog = response.getProgetto();
                    totalCount =  response.toString();
                    ////////////Progetto prog = (Progetto) response.getProperty(3);
                    //////////////totalCount = prog.toString();
            }
            catch (Exception e)
            {
                     e.printStackTrace();
            }


            //String totalCount = response.getProperty("Success").toString();
            //Object totalCount = response.getProperty(Progetto.class);



            //Object resultData = (SoapObject)response.getProperty(2);

            return "risposta dal WS = " + totalCount;
    }


}

и это классы для ProgettoResult и Progetto

package feronia.culturando.android;

import java.util.Hashtable;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class ProgettoResult implements KvmSerializable {


    private String          pSuccess;
    private String          pMessage;
    private Progetto        pProgetto;

    public Progetto getProgetto()
    {
            return pProgetto;
    }

    public void setProgetto(Progetto Progetto)
    {
            this.pProgetto = Progetto;
    }

    public ProgettoResult()
    {
            this.setSuccess("");
            this.setMessage("");
    }

    public ProgettoResult(String Success, String Message)
    {
            this.setSuccess(Success);
            this.setMessage(Message);
    }

    public Object getProperty(int arg0)
    {
            switch(arg0)
            {
            case 0:
                    return this.getSuccess();
            case 1:
                    return this.getMessage();
            case 2:
                    return this.getProgetto();
            }
            return null;
    }


    public int getPropertyCount()
    {
            return 3;
    }

    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) 
    {
            switch(index)
            {
            case 0:
                    info.name="Success";
                    info.type=PropertyInfo.STRING_CLASS;
                    break;
            case 1:
                    info.name="Message";
                    info.type=PropertyInfo.STRING_CLASS;
                    break;
            case 2:
                    info.name="Progetto";
                    info.type=Progetto.class;
                    break;
            default:
                    break;
            }
    }


    public void setProperty(int index, Object value) 
    {
            switch(index)
            {
            case 0:
                    this.setSuccess(value.toString());
                    break;
            case 1:
                    this.setMessage(value.toString());
                    break;
            case 2:
                    this.setProgetto((Progetto)value);
                    break;
            default:
                    break;
            }
    }
    /*********** GET - SET   *****************/

    public void setSuccess(String Success)
    {
            this.pSuccess = Success;
    }

    public String getSuccess()
    {
            return pSuccess;
    }

    public void setMessage(String Message)
    {
            this.pMessage = Message;
    }

    public String getMessage()
    {
            return pMessage;
    }
}

и

package feronia.culturando.android;

import java.util.Hashtable;

import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class Progetto implements KvmSerializable{

    private String pTitolo;
    private String pDescrizione;

    public Progetto()
    {
            this.setTitolo("");
            this.setDescrizione("");
    }

    public Progetto(String t,String d)
    {
            this.setTitolo(t);
            this.setDescrizione(d);
    }

    public Object getProperty(int index) 
    {
            switch(index)
            {
            case 0:
                    return this.getTitolo();
            case 1:
                    return this.getDescrizione();
            }
            return null;
    }


    public int getPropertyCount() 
    {
            return 2;
    }


    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) 
    {
            switch(index)
            {
            case 0:
                    info.name="Titolo";
                    info.type=PropertyInfo.STRING_CLASS;
                    break;
            case 1:
                    info.name="Descrizione";
                    info.type=PropertyInfo.STRING_CLASS;
                    break;
            default: 
                    break;
            }
    }


    public void setProperty(int index, Object value) 
    {
            switch(index)
            {
            case 0:
                    this.setTitolo(value.toString());
                    break;
            case 1:
                    this.setDescrizione(value.toString());
                    break;
            default: 
                    break;
            }
    }

    /*********** GET - SET   *****************/

    public void setTitolo(String Titolo)
    {
            this.pTitolo = Titolo;
    }


    public String getTitolo()
    {
            return pTitolo;
    }

    public void setDescrizione(String Descrizione)
    {
            this.pDescrizione = Descrizione;
    }

    public String getDescrizione()
    {
            return pDescrizione;
    }
}

есть кто-нибудь, кто может сказать мне, где ошибка ??? Пожалуйста, помогите мне, если сможете !!!

=============================================== =================================

большое спасибо himanshu и shadesco за интерес к моему вопросу !! Вот код моего класса активности, где находится вызывающая функция. Строка a вызова не является значимой в данный момент (еще не реализованы элементы управления для нее: я пропускаю несущественную строку), в то время как int b - это просто код проекта (progetto = 2), данные которого запрашиваются веб-службой. ,

запрос:

<soap:Body>
    <Progetto xmlns="http://tempuri.org/">
      <Guid>string</Guid>
      <Id_Progetto>int</Id_Progetto>
    </Progetto>
</soap:Body>

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

package feronia.culturando.android;

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

public class Presentazione extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.presentazione);


    webService cs=new webService();

    String appo=cs.Call("oi", 2);

    TextView pres_prog = (TextView) findViewById(R.id.pres_prog);

    pres_prog.setText(Html.fromHtml(appo));
}

}

Не думаю, что это важно, но полный ответ метода:

<soap:Body>
<ProgettoResponse xmlns="http://tempuri.org/">
  <ProgettoResult xmlns="">
    <Success>boolean</Success>
    <Message>string</Message>
    <Progetto>
      <Titolo>string</Titolo>
      <Descrizione>string</Descrizione>
      <Immagini>
        <Immagine xsi:nil="true" />
        <Immagine xsi:nil="true" />
      </Immagini>
    </Progetto>
  </ProgettoResult>
</ProgettoResponse>

есть еще один блок но при запросе progetto = 2 этот раздел ответа отсутствует (у проекта нет связанных изображений и тег

<Immagini /> 

не генерируется. Я пытаюсь идти шаг за шагом ...

Ответы [ 4 ]

0 голосов
/ 15 февраля 2012

Я думаю, что эта ссылка может помочь вам (она работает для меня): http://seesharpgears.blogspot.com/2010/10/ksoap-android-web-service-tutorial-with.html

0 голосов
/ 09 февраля 2012

Ну, я всегда помещаю одно и то же имя переменной в метод getPropertyInfo, я имею в виду:

у вас есть

...
case 0:
    info.name="Success";
    info.type=PropertyInfo.STRING_CLASS;
    break;
...

но переменная называется

private String pSuccess;

возможно, используя то же имя:

...
case 0:
    info.name="pSuccess";
    info.type=PropertyInfo.STRING_CLASS;
    break;
...
0 голосов
/ 09 февраля 2012

да, Франко, вместо того, чтобы продолжать писать свои комментарии выше, я напишу это здесь.

Хорошо, структура вашего запроса / ответа точна.однако ответ имеет:

<ProgettoResult xmlns="">
 <Success>boolean</Success>
 <Message>string</Message>
 <Progetto>
  <Titolo>string</Titolo>
  <Descrizione>string</Descrizione>
  <Immagini>
    <Immagine xsi:nil="true" />
    <Immagine xsi:nil="true" />
  </Immagini>
 </Progetto>

, что означает, что Object Progetto требует параметр Immagini (здесь это не очевидно, но я думаю, что это сложный тип, т.е. объект), НО, это позволяетего внутренние параметры должны быть NULL, то есть

<Immagine xsi:nil="true" />
<Immagine xsi:nil="true" />

-> nil = "true" ... так что это означает, что Immagini может бытьсвоего рода «пустой» объект.Итак, вам нужно создать класс для него, реализующий kvm serializable:

 public class Immagini implements KvmSerializable{
 //implement the overriden methods just like you did to Progetto
 }

И, тем не менее, вам все равно нужно ссылаться на него в классе Progetto.Так что вам нужно поставить ссылку на Иммагини:

public class Progetto implements KvmSerializable{

private String pTitolo;
private String pDescrizione;
private Immagini immagini;

public Progetto()
{
        this.setTitolo("");
        this.setDescrizione("");
       //Say put it null
       immagini = null;
}
//continue the rest of the code

Так что это означает, что ваш ответ, который Progetto требует THREE атрибутов ( Titolo, Descrizione, Immagini ):

 <Progetto>
  <Titolo>string</Titolo>
  <Descrizione>string</Descrizione>
  <Immagini>
    <Immagine xsi:nil="true" />
    <Immagine xsi:nil="true" />
  </Immagini>
 </Progetto>

Вы создали ссылку на все 3 из них.Скорее всего, для ответа требовалось 3 счетчик свойств, но вы давали только 2 , поэтому он не смог создать для него подходящий массив, он создал пустой Progetto = anyType {}

дайте мне знать, если это работает.

0 голосов
/ 09 февраля 2012

попробуйте это:

ProgettoResult pr = null;
try {
    httpTransport.call(SOAP_ACTION, envelope);
    pr = (ProgettoResult)envelope.getResponse();
} catch (Exception e) {
    e.printStackTrace();
}

Что такое totalCount?

...