java - Simple framework skip soap envelope and body -


i'm using retrofit , simple xml framework in android model soap response looks this:

xml:

<soap:envelope  xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/xmlschema" soap:encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:body>     <buslocationresponse          xmlns="at_web">         <version>1.0</version>         <responsecode>0</responsecode>         <input>             <route>801</route>             <direction>n</direction>         </input>         <vehicles>             <vehicle>                 <route>801</route>                 <direction>n</direction>                 <updatetime>09:42 pm</updatetime>                 <vehicleid>5007</vehicleid>                 <block>801-06</block>                 <adherance>-2</adherance>                 <adhchange>s</adhchange>                 <reliable>y</reliable>                 <offroute>n</offroute>                 <stopped>n</stopped>                 <inservice>y</inservice>                 <speed>20.61</speed>                 <heading> 3</heading>                 <routeid>44916</routeid>                 <positions>                     <position>30.221222,-97.765007</position>                     <position>30.218363,-97.766747</position>                     <position>30.215282,-97.768715</position>                     <position>30.212505,-97.770485</position>                     <position>30.204943,-97.774765</position>                     <position>30.204035,-97.775078</position>                 </positions>             </vehicle>         </vehicles> </buslocationresponse> </soap:body> </soap:envelope> 

really, care collection of vehicles. seems model buslocationresponse , skip soap envelope , body declaring

java:

@root(strict=false) @path("envelope/body/buslocationresponse") public class buslocationresponse {      @element(name="responsecode")     public int responsecode;      @elementlist     @path("envelope/body/buslocationresponse/vehicles")     public list<capvehicle> vehicles;  } 

this yields error:

org.simpleframework.xml.core.valuerequiredexception: unable satisfy @org.simpleframework.xml.element(data=false, name=responsecode, required=true, type=void) on field 'responsecode'  

what misunderstanding here?

you can't use @path on @root-element:

the path annotation used specify xml path xml element or attribute located.

( source )

since want nested data, somewhere deep in xml, there 2 solutions:

  1. map whole xml structure
  2. use converter cut's mapping down few classes , map those

and here's if choose no. 2:

the plan

  • a soapenvelope class builds root-element (<soap:envelope>...</soap:envelope>) , holds list of vehicles
  • a soapenvelopeconverter implements converter soapenvelope - there serialization reduced vehicles list only
  • a class vehicle holds data of elements (incl. class position <position>...</position> elements)
  • a class vehicles maps vehicles-tag (= list of vehicle elements).

(names have no convention)

the implementation

i've written implementation reference can see how suggested solution works. please add error checking etc. data fields handled string's here, replace types proper ones. only vehicles list deserialized, other values ignored. constructors, getter / setter etc. shown required example.

the deserialized vehicles list stored envelope's object. not best way , used example only. please write better implementation here (eg. introduce class soap body can manage contents).

note: classes implemented inner classes - optional, code prefer.

class soapenvelope / class soapenvelopeconverter (inner)

@root(name = "envelope") @namespace(prefix = "soap") // set converter that's used serialization @convert(value = soapenvelope.soapenvelopeconverter.class) public class soapenvelope {     // keep content of vehicles list here     private vehicles vehicles;       public vehicles getvehicles()     {         return vehicles;     }      protected void setvehicles(vehicles vehicles)     {         this.vehicles = vehicles;     }        // converter implementation soapenvelope     public static class soapenvelopeconverter implements converter<soapenvelope>     {         @override         public soapenvelope read(inputnode node) throws exception         {             soapenvelope envelope = new soapenvelope();             inputnode vehiclesnode = findvehiclesnode(node); // search vehicles list element              if( vehiclesnode == null )             {                 // bad - useful here                 throw new exception("no vehicles node!");             }              /*              * default serializer used deserialize full node.              * returned object set envelops's object, can              * through get()-method.              */             serializer ser = new persister();             envelope.setvehicles(ser.read(vehicles.class, vehiclesnode));              return envelope;         }           @override         public void write(outputnode node, soapenvelope value) throws exception         {             // if read (deserialize) there's no need implement             throw new unsupportedoperationexception("not supported yet.");         }           private inputnode findvehiclesnode(inputnode rootnode) throws exception         {             inputnode body = rootnode.getnext("body");             inputnode buslocationresponse = body.getnext("buslocationresponse");              inputnode next;              while( ( next = buslocationresponse.getnext() ) != null )             {                 if( next.getname().equals("vehicles") == true )                 {                     return next;                 }             }              return null;         }     } } 

class vehicles

@root(name = "vehicles") public class vehicles {     // maps list of vehicles     @elementlist(name = "vehicles", inline = true)     private list<vehicle> vehicles; } 

class vehicle

@root(name = "vehicle") public class vehicle {     // values of type string - please replace proper types     @element(name = "route")     private string route;     @element(name = "direction")     private string direction;     @element(name = "updatetime")     private string updatetime;     @element(name = "vehicleid")     private string vehicleid;     @element(name = "block")     private string block;     @element(name = "adherance")     private string adherance;     @element(name = "adhchange")     private string adhchange;     @element(name = "reliable")     private string reliable;     @element(name = "offroute")     private string offroute;     @element(name = "stopped")     private string stopped;     @element(name = "inservice")     private string inservice;     @element(name = "speed")     private string speed;     @element(name = "heading")     private string heading;     @element(name = "routeid")     private string routeid;     @elementlist(name = "positions")     private list<position> postions;       // class map position elements     @root(name = "position")     public static class position     {         @text()         private string position;     } } 

how use

final string xml = ... serializer ser = new persister(new annotationstrategy()); // annotation strategy set here!  soapenvelope soapenvelope = ser.read(soapenvelope.class, new stringreader(xml)); 

nothing special here - annotationstrategy required! source (2nd parameter of ser.read() set input comes. in example, soap xml comes string.


Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -