Set*_*eth 5 java android simple-framework retrofit
我正在使用Android中的RetroFitSimple XMLFramework来模拟SOAP响应,如下所示:
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>
Run Code Online (Sandbox Code Playgroud)
真的,我关心的只是车辆的集合.似乎我只能模拟BusLocationResponse并通过声明来跳过肥皂信封和身体
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;
}
Run Code Online (Sandbox Code Playgroud)
这只会产生错误:
org.simpleframework.xml.core.ValueRequiredException: Unable to satisfy
@org.simpleframework.xml.Element(data=false, name=Responsecode, required=true,
type=void) on field 'responseCode'
Run Code Online (Sandbox Code Playgroud)
我在这里误解了什么?
你不能@Path在@Root-Element上使用:
Path注释用于指定XML元素或属性所在的XML路径.
(来源)
由于您需要嵌套数据,从xml深处的某个位置,有两种解决方案:
如果你选择2号,这是怎么做的:
SOAPEnvelope类只构建root -element(<soap:Envelope>...</soap:Envelope>)并保存车辆列表SOAPEnvelopeConverter实现了Converter的SOAPEnvelope-有序列化是减少到只有车辆列表Vehicle保持这些元件的所有数据(包括一个类Position的<Position>...</Position>元素)Vehicles映射vehicles-tag(=车辆元素列表).(名称没有约定)
我已经编写了一个实现作为参考,因此您可以看到我的建议解决方案是如何工作的.请添加错误检查等.所有数据字段都String在这里处理,用正确的类型替换它们的类型.仅对车辆列表进行反序列化,忽略所有其他值.构造函数,getter/setter等仅显示为此示例所需的构造函数.
反序列化的车辆列表存储在信封的对象中.这不是最好的方法,仅用于举例.请在这里写一个更好的实现(例如,为肥皂体引入一个类,您可以在其中管理内容).
注意:有些类是作为内部类实现的- 这是可选的代码,如您所愿.
SOAPEnvelope/类(内部)SOAPEnvelopeConverter @Root(name = "Envelope")
@Namespace(prefix = "soap")
// Set the converter that's used for serialization
@Convert(value = SOAPEnvelope.SOAPEnvelopeConverter.class)
public class SOAPEnvelope
{
// Keep the content of vehicles list here
private Vehicles vehicles;
public Vehicles getVehicles()
{
return vehicles;
}
protected void setVehicles(Vehicles vehicles)
{
this.vehicles = vehicles;
}
// The converter implementation for 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 the Vehicles list element
if( vehiclesNode == null )
{
// This is bad - do something useful here
throw new Exception("No vehicles node!");
}
/*
* A default serializer is used to deserialize the full node. The
* returned object is set into the envelops's object, where you can
* get it through a 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 you read (deserialize) only there's no need to implement this
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Vehicles@Root(name = "Vehicles")
public class Vehicles
{
// Maps the list of vehicles
@ElementList(name = "Vehicles", inline = true)
private List<Vehicle> vehicles;
}
Run Code Online (Sandbox Code Playgroud)
Vehicle@Root(name = "Vehicle")
public class Vehicle
{
// All values are of type String - please replace with 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;
// A class to map the position elements
@Root(name = "Position")
public static class Position
{
@Text()
private String position;
}
}
Run Code Online (Sandbox Code Playgroud)
final String xml = ...
Serializer ser = new Persister(new AnnotationStrategy()); // Annotation strategy is set here!
SOAPEnvelope soapEnvelope = ser.read(SOAPEnvelope.class, new StringReader(xml));
Run Code Online (Sandbox Code Playgroud)
这里没有什么特别-仅AnnotationStrategy被要求!源(第二个参数ser.read()设置为您的输入.在此示例中,soap xml来自一个字符串.
| 归档时间: |
|
| 查看次数: |
3220 次 |
| 最近记录: |