gpt4 book ai didi

java - 简单的框架跳过肥皂信封和 body

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:26:21 26 4
gpt4 key购买 nike

我在 Android 中使用 RetroFit 和简单 XML 框架来模拟一个 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>

真的,我只关心车辆的收集。似乎我可以只对 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;

}

这只会产生错误:

org.simpleframework.xml.core.ValueRequiredException: Unable to satisfy
@org.simpleframework.xml.Element(data=false, name=Responsecode, required=true,
type=void) on field 'responseCode'

我在这里误解了什么?

最佳答案

您不能使用 @Path@Root -元素:

The Path annotation is used to specify an XML path where an XML element or attribute is located.

( Source )

由于你想要嵌套数据,从 xml 深处的某个地方,有两种解决方案:

  1. 映射整个 XML 结构
  2. 使用 Converter将映射减少到几个类并只映射那些

如果您选择第 2 项,则需要执行以下操作:

计划

  • A SOAPEnvelope 类仅构建元素 ( <soap:Envelope>...</soap:Envelope> ) 并保存车辆列表
  • A SOAPEnvelopeConverter 实现了一个 Converter对于 SOAPEnvelope - 那里序列化减少到仅车辆列表
  • A类 Vehicle 保存这些元素的所有数据(包括类 Position 用于 <Position>...</Position> 元素)
  • A类 Vehicles 映射 vehicles - 仅限标签(= 车辆元素列表)。

(名称没有约定)

实现

我已经编写了一个实现作为引用,因此您可以了解我建议的解决方案的工作原理。请添加错误检查等。所有数据字段都处理为 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;
}
}
}

Vehicles

@Root(name = "Vehicles")
public class Vehicles
{
// Maps the list of vehicles
@ElementList(name = "Vehicles", inline = true)
private List<Vehicle> vehicles;
}

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;
}
}

使用方法

final String xml = ...
Serializer ser = new Persister(new AnnotationStrategy()); // Annotation strategy is set here!

SOAPEnvelope soapEnvelope = ser.read(SOAPEnvelope.class, new StringReader(xml));

这里没什么特别的 - 只有 AnnotationStrategy必需的!来源(ser.read() 的第二个参数设置为您的输入。在此示例中,soap xml 来自字符串。

关于java - 简单的框架跳过肥皂信封和 body ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24102741/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com