Autore Topic: [ksoap2] Non riesco a passare oggetti commplessi  (Letto 2352 volte)

Offline helldron

  • Utente junior
  • **
  • Post: 68
  • Respect: 0
    • Mostra profilo
[ksoap2] Non riesco a passare oggetti commplessi
« il: 29 Novembre 2011, 12:16:51 CET »
0
Ciao a tutti,
quando faccio una chiamata ad un WS JAX-WS tramite ksoap2 tutto sembra andare a buon fine, il problema è che i parametri passati come variabili dirette come una String, un int etc.. arrivano al server mentre tutti i valori di un parametro complesso, come un oggetto "MioDTO" non arrivano mai.

EDIT: il marshal sia delle Date che dei BigDecimal è ok, anche il passaggio dei parametri almeno lato client.

In giro ho letto persino che i campi del DTO dovrebbero essere tutti minuscoli, ossia i nomi delle variabili e quindi anche dei tag generati ma non va lo stesso!

Non so più che inventarmi poichè le ho provate tutte!!

Innanzi tutto ecco la chiamata al mio WS traimte le ksoap2:

Codice: [Seleziona]
               
Log.i("MAIN_ACTIVITY","@@@@@ PREPARAZIONE CHIAMATA AL WS @@@@@");
       
SoapObject request = new SoapObject(AndSinistriAppConstants.WebServicesParameters.NAMESPACE, AndSinistriAppConstants.RetrieveSinistroByCriteriaParameters.METHOD_NAME);        // NAMESPACE, METHOD_NAME
       
        PropertyInfo propInfo = new PropertyInfo();
        propInfo.setName("inputfilter");
        propInfo.setValue(inputFilter);
        propInfo.setType(inputFilter.getClass());
        request.addProperty(propInfo);
       
        request.addProperty("inputfiliale", inputFiliale);
       
        Log.i("MAIN_ACTIVITY","@@@@@ num di property aggiunte alla request = " + request.getPropertyCount()+" @@@@@");
       
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.setOutputSoapObject(request);
        envelope.bodyOut = request;
        envelope.dotNet = true;
        envelope.setAddAdornments(false);
        envelope.implicitTypes= true;
        Log.i("MAIN_ACTIVITY","@@@@@ Envelope settata @@@@@");
       
        MarshalDate md = new MarshalDate();
        md.register(envelope);
       
        MarshalBigDecimal mbd = new MarshalBigDecimal();
        mbd.register(envelope);
       
        HttpTransportSE androidHttpTransport = new HttpTransportSE(AndSinistriAppConstants.WebServicesParameters.URL);        //URL
       
        try {
                envelope.addMapping(AndSinistriAppConstants.WebServicesParameters.NAMESPACE, "inputfilter",new AndSinistroInputDTO().getClass());
               
            androidHttpTransport.debug = true;
                        androidHttpTransport.call(AndSinistriAppConstants.RetrieveSinistroByCriteriaParameters.SOAP_ACTION, envelope);        //SOAP_ACTION
                       
                        SoapObject  resultsRequestSOAP = (SoapObject) envelope.getResponse();         //si può usare anche SoapPrimitive
                       
                        Log.i("MAIN_ACTIVITY","" + androidHttpTransport.requestDump);
                        Log.i("MAIN_ACTIVITY","" + androidHttpTransport.responseDump);

NB: inputFilter è un oggetto di tipo "AndSinistroInputDTO" che implementa KvmSerializable, Serializable.

Sotto c'è l'envelope che viene settata, allo stato attuale riesco a passare tutti i parametri ma sembra ci sia un problema più lato server:

Codice: [Seleziona]
<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>
                <retrieveSinistroByCriteria xmlns="http://blablabla">
                        <inputfilter>
                                <numero i:null="true"></numero>
                                <anno i:type="d:decimal" />
                                <ispettorato i:null="true"></ispettorato>
                                <numeroPolizza></numeroPolizza>
                                <dataDa i:type="d:dateTime">java.util.GregorianCalendar[time=1322521200000,areFieldsSet=true,lenient=true,zone=org.apache.harmony.luni.internal.util.ZoneInfo["CET",mRawOffset=3600000,mUseDst=true],firstDayOfWeek=1,minimalDaysInFirstWeek=4,ERA=1,YEAR=2011,MONTH=10,WEEK_OF_YEAR=48,WEEK_OF_MONTH=5,DAY_OF_MONTH=29,DAY_OF_YEAR=333,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=5,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=3600000,DST_OFFSET=0]</dataDa>
                        </inputfilter>
                        <inputfiliale>00060</inputfiliale>
                </retrieveSinistroByCriteria>
        </v:Body>
</v:Envelope>

Il valore anno è un BigDecimal quindi io ho implementato una classe MarshalBigDecimal che è fatta così:

Codice: [Seleziona]
ublic class MarshalBigDecimal implements Marshal{

        public static Class BIG_DECIMAL_CLASS = new BigDecimal(0).getClass();
       
         public void register(SoapSerializationEnvelope envelope) {
                 
                 envelope.addMapping(envelope.xsd, "decimal", MarshalBigDecimal.BIG_DECIMAL_CLASS, this);
         }

        @Override
        public Object readInstance(XmlPullParser arg0, String arg1, String arg2, PropertyInfo arg3) throws IOException, XmlPullParserException {
                return null;
        }

        @Override
        public void writeInstance(XmlSerializer arg0, Object arg1) throws IOException {               
        }
}

Nel metodo che fa la chiamata al WS poi uso:
Codice: [Seleziona]
MarshalBigDecimal mbd = new MarshalBigDecimal();
mbd.register(envelope);

EDIT: Ho provato a fare il marshal anche dell'oggetto AndsinistroInputDTO come per le Date e i BigDecimal, tuttavia l'attributo i:type="..." non è presente nella request

Secondo me non riesce proprio a costruirsi lato server l'oggetto inputFilter.
« Ultima modifica: 12 Dicembre 2011, 09:11:50 CET da helldron »

Offline helldron

  • Utente junior
  • **
  • Post: 68
  • Respect: 0
    • Mostra profilo
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #1 il: 19 Dicembre 2011, 15:54:53 CET »
0
Sono arrivato al punto che la request è corretta, cioè tutti i valori vengono impostati per l'oggetto complesso, ma lato server che è WebSphere non riceve i parametri ma solo per l'oggetto complesso con tutti i campi a null.

Sono quasi sicuro che ciò che sbaglio è questa istruzione che viene spesso sottovalutata nei tutorial.
 
Citazione
envelope.addMapping(AndSinistriAppConstants.WebServicesParameters.NAMESPACE, "inputfilter",new AndSinistroInputDTO().getClass());

Che cosa vuol dire esattamente questo mapping??

In giro ho trovato questa nota:
Citazione
use SoapSerializationEnvelope addMapping with the namespace, the name of the class (as in the wsdl) and the class (getClass() or .class) itself

Ho fatto delle prove dando il tipo che si aspetta il server al posto di AndSinistroInputDTO() e anche il nome del parametro sempre lato server ma va in eccezzione quando fornisco il .getClass(). Dice ClassNotFoundError anche se includo il .jar nel progetto Android.

Qualche aiuto???
« Ultima modifica: 19 Dicembre 2011, 15:58:13 CET da helldron »

Offline helldron

  • Utente junior
  • **
  • Post: 68
  • Respect: 0
    • Mostra profilo
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #2 il: 27 Gennaio 2012, 11:44:01 CET »
0
UP  ;-)

Offline dom4

  • Utente normale
  • ***
  • Post: 158
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Vodafone Ideos, Nexus 5
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #3 il: 28 Gennaio 2012, 16:31:19 CET »
0
Solo una volta mi sono trovato a dover passare un tipo complesso tramite ksoap e questo è il codice che ho utilizzato,spero possa esserti di aiuto:
Codice (Java): [Seleziona]
 
//Creao un array di tipo ProdottoConcorsoTransazionePunti
 ProdottoConcorsoTransazionePunti[] ListaProdotti = new ProdottoConcorsoTransazionePunti[listaInseriti.size()+1]; //listaInseriti è un ArrayList<ProdottoConcorsoTransazionePunti>

                        int i = 0;
                        ProdottoConcorsoTransazionePunti current = null;
                         for(ProdottoConcorsoTransazionePunti pc : listaInseriti)
                         {
                                 current = new ProdottoConcorsoTransazionePunti();
                                 current.setID_Prodotto(pc.getID_Prodotto());
                                 current.setQuantitaAcquistata(pc.getQuantitaAcquistata());
                                 ListaProdotti[i] = current;
                                 i++;
                                 current = null;
                         }
                     
                         SoapObject prodotti = new SoapObject (NAMESPACE,"ListaProdotti");
                         SoapObject ProdottoConcorsoTransazionePunti=null;
                              for(int x=0;x<ListaProdotti.length;x++)
                              {
                                 Log.i("","Dimensione" + ListaProdotti.length);
                                 if(ListaProdotti[x]!=null)
                             {
                           ProdottoConcorsoTransazionePunti = new SoapObject(NAMESPACE,"ProdottoConcorsoTransazionePunti");
                           ProdottoConcorsoTransazionePunti.addProperty("ID_ProdottoConcorso", ListaProdotti[x].getID_Prodotto());
                            Log.i("","" + ListaProdotti[x].getID_Prodotto());
                           ProdottoConcorsoTransazionePunti.addProperty("QuantitaAcquistata", ListaProdotti[x].getQuantitaAcquistata());
                           Log.i("","" + ListaProdotti[x].getQuantitaAcquistata());
                           Log.i("Seeting","Variabili inizializzate");
                           prodotti.addProperty("ProdottoConcorsoTransazionePunti",ProdottoConcorsoTransazionePunti);
                           }
                           ProdottoConcorsoTransazionePunti=null;
                              }
                           
                       
                               request.addProperty("prodotti", prodotti);
                   
                               
L'ho fatto un pò di tempo fa e per me funzionava,spero possa esserti di aiuto.L'unico consiglio ulteriore che posso darti è quello di stare attento a come devo essere scritti i parametri e gli oggetti da passare(lettera minuscola,maiuscola),agli inizi anche io non riuscivo a capire perchè non mi funzionassero le chiamate. ;-)

Offline helldron

  • Utente junior
  • **
  • Post: 68
  • Respect: 0
    • Mostra profilo
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #4 il: 30 Gennaio 2012, 09:09:35 CET »
0
Puoi postare la parte del wsdl relativa a quella chiamata che fai? e magari anche eventuale .xsd se ce l'hai, nel senso se hai un xml che ti descrive i tipi complessi!!

Farò altre prove ma il problema potrebbe essere che il mio oggetto lato Web Serivce estende un oggetto generico, dal file .xsd infatti ho

Codice: [Seleziona]
<xs:complexType name="retrieveSinistroByCriteria">
    <xs:sequence>
      <xs:element name="arg0" type="tns:sinistroInputDTO" minOccurs="0"/>
      <xs:element name="arg1" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="sinistroInputDTO">
    <xs:complexContent>
      <xs:extension base="tns:abstractBaseDTO">
        <xs:sequence>
          <xs:element name="anno" type="xs:decimal" minOccurs="0"/>
          <xs:element name="dataInizioCoperturaA" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="dataInizioCoperturaDa" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="dataSinistroA" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="dataSinistroDa" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="ispettorato" type="xs:string" minOccurs="0"/>
          <xs:element name="nominativoContraente" type="xs:string" minOccurs="0"/>
          <xs:element name="nominativoControparte" type="xs:string" minOccurs="0"/>
          <xs:element name="numeroPolizza" type="xs:string" minOccurs="0"/>
          <xs:element name="numeroSinistro" type="xs:string" minOccurs="0"/>
          <xs:element name="targaContraente" type="xs:string" minOccurs="0"/>
          <xs:element name="targaControparte" type="xs:string" minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

Grazie mille.

Offline dom4

  • Utente normale
  • ***
  • Post: 158
  • Respect: +1
    • Mostra profilo
  • Dispositivo Android:
    Vodafone Ideos, Nexus 5
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #5 il: 30 Gennaio 2012, 15:51:46 CET »
0
Puoi postare la parte del wsdl relativa a quella chiamata che fai? e magari anche eventuale .xsd se ce l'hai, nel senso se hai un xml che ti descrive i tipi complessi!!

Farò altre prove ma il problema potrebbe essere che il mio oggetto lato Web Serivce estende un oggetto generico, dal file .xsd infatti ho

Codice: [Seleziona]
<xs:complexType name="retrieveSinistroByCriteria">
    <xs:sequence>
      <xs:element name="arg0" type="tns:sinistroInputDTO" minOccurs="0"/>
      <xs:element name="arg1" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="sinistroInputDTO">
    <xs:complexContent>
      <xs:extension base="tns:abstractBaseDTO">
        <xs:sequence>
          <xs:element name="anno" type="xs:decimal" minOccurs="0"/>
          <xs:element name="dataInizioCoperturaA" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="dataInizioCoperturaDa" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="dataSinistroA" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="dataSinistroDa" type="xs:dateTime" minOccurs="0"/>
          <xs:element name="ispettorato" type="xs:string" minOccurs="0"/>
          <xs:element name="nominativoContraente" type="xs:string" minOccurs="0"/>
          <xs:element name="nominativoControparte" type="xs:string" minOccurs="0"/>
          <xs:element name="numeroPolizza" type="xs:string" minOccurs="0"/>
          <xs:element name="numeroSinistro" type="xs:string" minOccurs="0"/>
          <xs:element name="targaContraente" type="xs:string" minOccurs="0"/>
          <xs:element name="targaControparte" type="xs:string" minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

Grazie mille.

Purtroppo non posso farlo perchè in seguito il metodo è stato cambiato e non c'è stato più bisogno di quel tipo di chiamata,comunque dovresti provare a fare un semplice client in java che ti effettui la stessa chiamata per vedere se funziona,così facendo capirai se il problema è il tuo o del WS

Offline helldron

  • Utente junior
  • **
  • Post: 68
  • Respect: 0
    • Mostra profilo
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #6 il: 10 Febbraio 2012, 11:17:19 CET »
0
Ho cambiato approccio e ho deciso di deployare il WS su un'altro application server perchè WebSphere non da praticamente nessun errore o avviso:

Ho deployato il WS su JBoss6 , quello che accade è che quando passo l'oggetto complesso avviene un eccezione bloccante che potrebbe quindi identificare meglio il problema.

Codice: [Seleziona]
Unmarshalling Error: unexpected element (uri:"http://proxy.ws.business.it", local:"arg
"). Expected elements are <{}arg1>,<{}arg0>

e la causa

Codice: [Seleziona]
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://proxy.ws.business.sinistri.it", local:"arg0"
. Expected elements are <{}arg1>,<{}arg0>

Ho fatto delle prove e delle ricerche su internet, sembra che i tag del body della request che devo passare debbano avere una forma di questo tipo <tag> invece di <n0:tag> per esempio. Il fatto è che la mia envelope è già così e i parametri ora li ho chiamati "arg0" e "arg1". Eppure c'è ancora l'errore.

Attualmente il codice è così:

Codice: [Seleziona]
SoapObject request = new SoapObject(AndSinistriAppConstants.WebServicesParameters.NAMESPACE, AndSinistriAppConstants.RetrieveSinistroByCriteriaParameters.METHOD_NAME);        // NAMESPACE, METHOD_NAME
     
       
        PropertyInfo propInfo = new PropertyInfo();
        propInfo.setName("arg0");                 
        propInfo.setValue(inputFilter);
        propInfo.setType(inputFilter.getClass());
        //propInfo.setNamespace(AndSinistriAppConstants.WebServicesParameters.NAMESPACE);
        request.addProperty(propInfo);
       
//        PropertyInfo propInfoFil = new PropertyInfo();
//        propInfoFil.setName("arg1");
//        propInfoFil.setNamespace(AndSinistriAppConstants.WebServicesParameters.NAMESPACE);
//        request.addProperty(propInfoFil);
        request.addProperty("arg1", inputFiliale);
.
.
envelope.addMapping(AndSinistriAppConstants.WebServicesParameters.NAMESPACE, "sinistroInputDTO", new AndSinistroInputDTO().getClass());

Forse la risoluzione di questo problema per me sblocca anche l'altro, perchè JBoss mi sembra molto più schizzinoso.

Qualche suggerimento?? Grazie

Offline ivano

  • Nuovo arrivato
  • *
  • Post: 11
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    SGS2
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #7 il: 13 Febbraio 2012, 23:58:35 CET »
0
Domanda: lato server l'applicazione è tua?
Altra domanda: i web services sono utilizzati anche da altri client oltre all'applicazione Android?

Te lo chiedo perché se devi dialogare solo con Android ti consiglio di non usare i web services, che sono anche pesanti da gestire. Puoi spedire avanti e indietro oggetti serializzati. Ti serve API level 8.

Ciao
Ivano

Offline helldron

  • Utente junior
  • **
  • Post: 68
  • Respect: 0
    • Mostra profilo
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #8 il: 15 Febbraio 2012, 11:22:55 CET »
0
Il WS lo controllo io, l'ho fatto io :) però sono obbligato a usare le ksoap2, è per un progetto!

Offline ivano

  • Nuovo arrivato
  • *
  • Post: 11
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    SGS2
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #9 il: 15 Febbraio 2012, 16:43:38 CET »
0
Il WS lo controllo io, l'ho fatto io :) però sono obbligato a usare le ksoap2, è per un progetto!

Purtroppo con i web services che dialogano con frameworks eterogenei ho sempre avuto da battagliare.
Posso consigliarti di testare il lato server con questa utility per verificare che da quel lato almeno non ci siano problemi.
Se hai il tempo e la possibilità puoi fare una implementazione al volo del web service su AJAX2, con il plugin di Eclipse hai tutto pronto in poco tempo.

Offline helldron

  • Utente junior
  • **
  • Post: 68
  • Respect: 0
    • Mostra profilo
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #10 il: 15 Febbraio 2012, 16:51:22 CET »
0
Grazie ivano, in realtà io riesco a usare perfettamente il WS sia con soapUI che con un Framework come Axis o Axis 2. Vedrò un attimo la storia di Ajax2 appena avrò tempo (ma forse intendevi Axis2 ??).

Offline ivano

  • Nuovo arrivato
  • *
  • Post: 11
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    SGS2
Re:[ksoap2] Non riesco a passare oggetti commplessi
« Risposta #11 il: 15 Febbraio 2012, 16:56:10 CET »
0
Grazie ivano, in realtà io riesco a usare perfettamente il WS sia con soapUI che con un Framework come Axis o Axis 2. Vedrò un attimo la storia di Ajax2 appena avrò tempo (ma forse intendevi Axis2 ??).

Si certo, intendevo il server AXIS, io lo faccio girare su Tomcat.