简单的框架跳过SOAP信封,体 [英] Simple framework skip soap envelope and body

查看:287
本文介绍了简单的框架跳过SOAP信封,体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用改装和简单 XML 框架在Android中到 SOAP模型响应,看起来像这样:

I'm using RetroFit and Simple XML Framework in Android to model a SOAP response that looks like 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>

真的,我所关心的是车辆的集合。好像我可以模拟只是BusLocationResponse并宣布跳过SOAP信封,体

Really, all I care about is the collection of vehicles. It seems like I could model just the BusLocationResponse and skip the soap envelope and body by declaring the

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' 

我是什么误解吗?

What am I misunderstanding here?

推荐答案

您不能使用 @Path @root -Element:

You can't use @Path on @Root-Element:

路径注解用于指定一个XML元素或属性位于一个XML路径。

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

(<一个href=\"http://simple.sourceforge.net/download/stream/doc/javadoc/index.html?org/simpleframework/xml/Root.html\"相对=nofollow>来源)

由于您希望嵌套的数据,从XML深的地方,有两种解决方法:

Since you want nested data, from somewhere deep in the xml, there are two solutions:


  1. 地图整个XML结构

  2. 使用一个<一个href=\"http://simple.sourceforge.net/download/stream/doc/javadoc/index.html?org/simpleframework/xml/Root.html\"相对=nofollow>转换器这伤口的映射下至几类和地图只是那些

  1. Map the whole XML structure
  2. Use a Converter that cut's mapping down to few classes and map just those

和这里做什么,如果你选择第2号

And here's what to do if you choose No. 2:


  • A 的SoapEnvelope 类构建刚刚的的-element(&LT;肥皂:信封&GT; ...&LT; / SOAP:信封&GT; ),并拥有车辆的名单

  • A SOAPEnvelopeConverter 实现了一个转换的SoapEnvelope - 有序列化降低车辆只列出

  • 类的 汽车 持有这些元素的所有数据(包括一类的 位置 &LT;&定位GT; ...&LT; /位置&GT; 元素)

  • 类的 汽车 车辆地图 -tag只(=车辆名单元素)。

  • A SOAPEnvelope class builds just the root-element (<soap:Envelope>...</soap:Envelope>) and holds the list of vehicles
  • A SOAPEnvelopeConverter implements a Converter for SOAPEnvelope - there the serialization is reduced to vehicles list only
  • A class Vehicle holds all the data of those elements (incl. a class Position for the <Position>...</Position> elements)
  • A class Vehicles maps the vehicles-tag only (= list of vehicle elements).

(名没有约定)

我已经写了一个实现作为参考,所以你可以看到我的建议的解决方案是如何工作的。请添加错误检查等所有数据字段为字符串的位置,适当的进行更换它们的类型进行处理。的只有的车辆列表进行反序列化,将被忽略所有其他值。构造函数,的getter / setter等,因为它们都需要在这个例子中才会显示。

I've written an implementation as a reference so you can see how my suggested solution works. Please add error checking etc. All data fields are handled as String's here, replace their types with proper ones. Only the vehicles list is deserialized, all other values are ignored. Constructors, getter / setter etc. are only shown as they are required for this example.

的反序列化的车辆清单存入信封的对象。这不是最好的方法和用于例如仅。请写在这里更好地执行(如引入肥皂身体,你可以管理内容类)。

The deserialized vehicles list is stored into the envelope's object. This is not the best way and used for example only. Please write a better implementation here (eg. introduce a class for the soap body where you can manage contents).

请注意:有些类被实现为的的内部类的 - 这是可选的,code作为您preFER

Note: Some classes are implemented as inner classes - this is optional, code as you prefer.

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

类的 汽车

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

类的 汽车

@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来自一个字符串。

Nothing special here - only AnnotationStrategy is required! The source (2nd parameter of ser.read() is set as your input comes. In this example, the soap xml comes from a string.

这篇关于简单的框架跳过SOAP信封,体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆