Menu

RE: Serializing complex objects

Help
2006-06-09
2013-04-25
1 2 > >> (Page 1 of 2)
  • James Seigel

    James Seigel - 2006-06-09

    OOPs...taking a closer look at your last response xml you might want to change your mapping from "DataClass" to "lookUpReturn"  Then your original code will work with out my getproperty hack.

    I love .NET

     
    • Isaac

      Isaac - 2006-06-11

      Posted code with output here.
      I'm stumped. It won't go...

      http://svn.manageudaserver.com/portable/phoneClient/ 

       
    • James Seigel

      James Seigel - 2006-06-11

      Correct.  Your code as written will not work.

      I am going to try and give you some tools to work with, since what we are trying to get to work has changed since you originally asked the question, so our suggestions have been given for a moving target. 

      Here are some things that might help you out....

      1) The client you are using has absolutely know knowlege of the wsdl that you have created.  All it knows about when trying to decode the xml message that it gets back, is what is contained within the xml message.  This means to get it working quickly, forget everything you know and pretend that you are the client seeing the message for the very first time.

      a) Mentally throw out everything except what is between the body tags.  This leaves: 
      *        <lookUpResponse xmlns="http://ksoap2">
      *            <lookUpReturn>
      *                <name>Me!</name>
      *                <number>64</number>
      *            </lookUpReturn>
      *        </lookUpResponse>

      b) Looking at this you see that you have an element "lookUpResponse" in namespace http://ksoap2 which has a one subelement of lookupReturn with no namespace, which has two subelements of name and number with no namespace.

      c) Wrapping your head around this a little bit, the lookUpReturn element kinda looks like the ReturnDataClass object that you are trying to populate.  So add a mapping to that effect. name = "lookUpReturn" namespace="".  Okay lets write the code for that:

      envelope.addMapping("", "lookUpReturn", new RequestDataClass().getClass());

      There we are.  Now when ksoap sees a lookup return with no namespace it will think....RequestDataClass!!  One thing down.

      2) The getResponse and the old getResult methods held the developers hands a bit knowing that for about 90% of the calls the result was going to be returned in an element that looked an aweful lot like the "lookUpResponse" element.  Therefore the implementation of that method says...return the first element of the soapobject that we have stuffed lookUpResponse into which will more than likely be the object that the developer was looking for anyway.  In this case it looks like that would be true given your response information.

      Now, I am going to do something risky because I don't have a whole heck of a lot of time this afternoon and say, hey that should do it and not test it on you.  Basically it should work with the information that I have given you.  I hope that you can understand the logic behind the mapping information I have given you this time, and can therefore shift your code appropriately if you change information or deployment.

      Good luck and I hope you can figure stuff out.  Just a note, namespaces are tricky things and they can cause all sorts of hillarity if you aren't careful.

      Good luck.  If for some reason that doesn't work for you...try me one more time and I will test it and give you a tested solution.

      James.

       
      • James Seigel

        James Seigel - 2006-06-12

        Oh, and you will never be able to cast the result to DataClass as you have mapped the result to RequestDataClass, so you should cast it to the object you mapped the result to.

        Cheers
        J....I am looking to test it right now....

         
        • James Seigel

          James Seigel - 2006-06-12

          Here, this will get you started:

                  SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                  SoapObject template = new SoapObject("http://ksoap2","lookUpResponse");
                  PropertyInfo propertyInfo = new PropertyInfo();
                  propertyInfo.name="lookUpReturn";
                  propertyInfo.type = new RequestDataClass().getClass();
                  template.addProperty(propertyInfo, "irrelavent");
                  envelope.addTemplate(template);
                  envelope.addMapping("", "lookUpReturn", new RequestDataClass().getClass());
          //        envelope.addMapping("http://ksoap2", "RequestDataClass", new RequestDataClass().getClass());
                  envelope.implicitTypes = true;
                  envelope.setOutputSoapObject(request);

           
          • Jim Redman

            Jim Redman - 2006-06-12

            Here's the reverse of a question you asked me.  What have you got against SoapObjects?

            I haven't looked at the code, but having used all three mechanisms, I think that using a SoapObject to represent other objects, including the wrapper that I create with WSDL2Java is cleaner and easier to understand than using KVMSerializable or a custom Marshal.

            This is just my, largely uniformed, opinion and I'm wondering if I missed something significant.

            Jim

             
            • Isaac

              Isaac - 2006-06-12

              Nothing. Except when I'm sending a vector of classes, its cleaner to serialize and deserialize the classes once the mapping is set up properly.

               
            • James Seigel

              James Seigel - 2006-06-12

              Jim,

              SoapObjects are grand. I think the next bout of help I dish out in terms of examples I am going to do it with soapobjects to show a balance here.

              Now that Isaac is in love and working, I can get back to integrating your code.  I am floating the idea of adding the attributes as an "extra" to the codebase.  It kinda feels like a separate aspect...but I will post more on the appropriate thread when I have poked the code a bit more

              J

               
              • Jim Redman

                Jim Redman - 2006-06-15

                Umm,  I think that attributes are as much a part of the standard as properties and I think that KSoap should be aiming at full standard support.  There are a number of objects I've been dealing with that have only attributes, so you could say that properties feel "like a separate aspect" - they're not, they're different and not interchangable, but both are essential.

                It probably does make sense to open another thread.  SOAP is about interoperability, and without attributes you don't have that.  I think that the future of SOAP is interface definitions (WSDL) and code generation, and that means support for the full standard.

                Jim

                 
          • Isaac

            Isaac - 2006-06-12

            It works!
            I love you!
            Thanks!!!!!

             
          • Isaac

            Isaac - 2006-06-12

            I apologize for doing this to you...
            I think I'm getting how it works, though.

            ------------------------------------------
            propertyInfo.name="lookUpReturn";
            propertyInfo.type = new RequestDataClass().getClass();
            /** propertyInfo in SOAP:
            * <lookUpReturn>
            *   <RequestDataClassType/>
            * </lookUpReturn>
            * or
            * <lookUpReturn>
            *   <name/>
            *   <number/>
            * </lookUpReturn>
            */

            SoapObject template = new SoapObject("http://ksoap2", "lookUpResponse");
            template.addProperty(propertyInfo, "irrelavent");
            /** template in SOAP
            * <lookUpResponse xmlns="http://ksoap2">
            *   <lookUpReturn>
            *     <name/>
            *     <number/>
            *   </lookUpReturn>
            * </lookUpResponse>
            */
                   

            envelope.addTemplate(template);
            envelope.addMapping("", "lookUpReturn", new RequestDataClass().getClass());
            ---------------------------------------------

            The body of the response looks like:
            * <lookUpResponse xmlns="http://ksoap2">
            *   <lookUpReturn>
            *     <name/>
            *     <number/>
            *   </lookUpReturn>
            * </lookUpResponse>
            If I return a vector or array, the body looks like:
            * <lookUpResponse xmlns="http://ksoap2">
            *   <lookUpReturn>
            *     <name/>
            *     <number/>
            *   </lookUpReturn>
            *   <lookUpReturn>
            *     <name/>
            *     <number/>
            *   </lookUpReturn>
            * </lookUpResponse>
            So I was thinking either:
            1) Rather than mapping the whole double-wrapped <lookUpResponse> to ResponseDataClass, just map the inner <lookUpReturn> to the class. This way individual <lookUpReturn>'s can be entracted  from the <lookUpResponse>, by mapping the <lookUpResponse> to a SoapObject and casting the getProperty(i).
            2) Rather than mapping the ReturnDataClass, map either a Vector or ReturnDataClass array
            3) Take a look at the existing code that's posted here somewhere  for returning Vectors.

            Please advise...

             
            • Isaac

              Isaac - 2006-06-13

              Bump?

               
              • James Seigel

                James Seigel - 2006-06-13

                Damn potholes in the road.....

                 
              • James Seigel

                James Seigel - 2006-06-13

                There are two ways of doing it....
                1) look at how it was done for the amazon search demo and kind of do it like that...
                2) the other is just just store the results of the setLookUpReturn() method into a vector everytime it is called.
                3) Probably a soapobject way that I can't think of right now, but jim might have some insight into.

                James.

                 
                • Jim Redman

                  Jim Redman - 2006-06-13

                  What me?  I've been off in building automation land where they talk BACnet not SOAP.

                  I don't really know, but here's my quick thoughts.  Since it's a ComplexType, you should treat it as a complext type.  If you try to keep two arrays that have to be in the same order you'll get burnt one day (it's workable and within spec. but it's not robust).

                  You can encode multiple attributes with the same name within a SoapObject:

                  soapObject.addAttribute ("attribute", someObject1);
                  soapObject.addAttribute ("attribute", someObject2);
                  soapObject.addAttribute ("attribute", someObject3);
                  ...

                  but you have to enumerate the hashtable at the end so the order is lost.

                  You could also make the phone number an attribute of the name, this would allow you to just add a simple attribute.
                  <response>
                  <name phone=xxxxxx>Larry</name>
                  <name phone=yyyyyy>Moe</name>
                  <name phone=zzzzzz>Curly</name>
                  </response>

                  That might make sense from a database standpoint since the attribute can be null (non-existant) but (presumably) a name is required.  You could have the address, town, postcode, etc. as attributes and just include the ones you know.

                  Just go and find a WSDL for somebody who's done something similar and see what they did.  I hate to invent stuff when someone's already thought through the problem more thoroughly than I.

                  Jim

                   
                • Isaac

                  Isaac - 2006-06-15

                  I feel so dumb...
                  How does the adding a template help?
                  Why is it only done sometimes?
                  I tried adding a vector to the dataClass Object being returned, and stuck two strings in the vector. It worked. But now its not.
                  The Amazon thing confuses me.
                  I tried to base me stuff on it, but got no where...

                   
                  • Isaac

                    Isaac - 2006-06-15

                    Edit. Where's the edit button?
                    Now I feel dumber.
                    It stopped working because I restored my files and I only implemented the vector in one of the two.
                    I'm still confused about the template and the whole amazon thing...

                     
                  • Isaac

                    Isaac - 2006-06-15

                    Can I get an explanantion for:

                            PropertyInfo propertyInfo = new PropertyInfo();
                            propertyInfo.name="lookUpReturn";
                            propertyInfo.type = new RequestDataClass().getClass();

                            SoapObject template = new SoapObject("http://ksoap2", "lookUpResponse");
                            template.addProperty(propertyInfo, "irrelavent");

                            SoapObject request = new SoapObject("http://ksoap2", "lookUp");
                            request.addProperty("lookupData", getRequestDataClass());

                            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                            envelope.addTemplate(template);
                            envelope.addMapping("", "lookUpReturn", new RequestDataClass().getClass());

                    I'm still struggling with the Amazon thing...
                    That doesn't have templates....

                    What I'm doing now:
                    Sending a RequestDataClass.
                    Receiving a ResponsePackage which contains a Vector or ContactItem's

                    3 types to register somehow...
                    I think it's similar to the Amazon but I'm too tired to work it out ATM.

                    Code still at
                    http://svn.manageudaserver.com/portable/phoneClient/
                    and
                    http://svn.manageudaserver.com/portable/phoneServ/

                     
                  • Isaac

                    Isaac - 2006-06-16

                    Now that I built my own complex multi-class return item, I'm starting to understand how the Amazon thing works. Suprisingly, it's actually more similar to my project than I realized.
                    I'm using it to build my project...

                     
                  • Isaac

                    Isaac - 2006-06-16

                    Well... I think my code is quite similar to the Amazon code. But mine isn't working
                    How do I go about debugging it?

                    http://svn.manageudaserver.com/portable/phoneClient/ 
                    http://svn.manageudaserver.com/portable/phoneServ/

                     
    • James Seigel

      James Seigel - 2006-06-12

      So Isaac,

      What are you studying at UoT and what are you using ksoap2 for? 

      Just curious after all your efforts.

      J

       
      • Isaac

        Isaac - 2006-06-12

        I am studying engineering. First term it was Engineering Science which is basically all other 8 fields of engineering rolled into one
        The second term I decided I dislike spending my every waking moment studying just to stay average (albiet of the top group of students in UofT). So I dropped into Electrical and Computer Engineering.
        I reviewed some C/C++ during the first term (taking the 'advance computers option') but no Java...

        This summer I'm working for RentMagic.ca writing a mini version of the property management software in Java so property managers can access their databases using Java enabled browsers or BlackBerrys.

         
        • James Seigel

          James Seigel - 2006-06-12

          Neat,

          Good luck!

          James.

           
    • Isaac

      Isaac - 2006-06-21

      *sigh*
      I'm back.
      Simple class: a class that only contains Strings + ints + Integers
      I managed to get working:
      Sending simple class A to the server
      Deserializing simple class B from the server
      Deserializing a class that contains a Vector <String> from the server
      (Available as branches on my SVN)

      Next step: deserializing a class that contains a simple class in it.
      If it helps, Axis produces the WSDL but I can't read it...
      http://svn.manageudaserver.com/portable/phoneServ/trunk/WebContent/wsdl/

      When getting a simple class, I do envelope.addMapping() to register the class then I add a template of the class inside a SOAP object, which takes care of the second level of wrapper...

      For the getPropertyInfo(), I need the type (e.g. info.type = PropertyInfo.VECTOR_CLASS;).
      If the type the same as .getClass, i.e. can the above line be replaced with info.type = Vector().getClass(); ?

      Can someone explain how this stuff works and how to register/deserialize the class-within-a-class?

      Thanks!

      http://svn.manageudaserver.com/portable/phoneServ/
      http://svn.manageudaserver.com/portable/phoneClient/

       
1 2 > >> (Page 1 of 2)

Log in to post a comment.