simplexml xml网络请求填坑

2020-06-24  本文已影响0人  忧郁的小码仔

最近公司要开发一个老项目的移动端,后台还是使用的webservice,接口数据交换使用XML,下面是其中一个接口的参数Demo:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Header>
        <AuthorityHead xmlns="xxxxxx">
            <auth>
                <user>admin</user>
                <pwd>admin</pwd>
            </auth>
        </AuthorityHead>
    </soap:Header>
    <soap:Body>
        <clientwarehouseOut xmlns="xxxxxxx">
            <orderNumber xmlns="">xxxxxx</orderNumber>
            <id xmlns="">xxx</id>
            <orderList  xmlns="">xxxxxxxxx</orderList>
            <orderList  xmlns="">xxxxxxxxx</orderList>
            <orderList  xmlns="">xxxxxxxxx</orderList>
            <orderList  xmlns="">xxxxxxxxx</orderList>
            <eventTime xmlns="">2020-04-30T14:44:19</eventTime>
        </clientwarehouseOut>
    </soap:Body>
</soap:Envelope>

XML解析和网络请求的话用的是Retrofitsimplexml,这里为了不耽误大家时间,直接说下遇到的一些问题,具体的Demo有需要的可以私信。

第一个问题:<orderList xmlns="">标签这里的namespace怎么处理?

我这边一开始是这样写的:

@Namespace
@ElementList(inline = true, entry = "orderList")
public List<String> orderList;

但是,结果生成xml请求后发现@Namespace注解没起作用,生成的标签是这样的:

<orderList>xxxxxx</orderList>
<orderList>xxxxxx</orderList>

最后,只能曲线救国,自己新建了一个class替换掉String:

@Root(name = "orderList")
@Namespace
public class CustomeOrder {
    @Text
    public String order;
    // ......
}

外面改成这样:

    @Namespace
    @ElementList(inline = true, entry = "orderList")
    public List<CustomeOrder> orderList;

这样,生成的orderList标签就有namespace了:

            <orderList  xmlns="">xxxxxxxxx</orderList>
            <orderList  xmlns="">xxxxxxxxx</orderList>

第二个问题:simplexml生成的xml标签顺序问题

我本来xml顺序是这样的:

<soap:Header>
....
</soap:Header>
<soap:Body>
....
</soap:Body>

但是,simplexml默认生成的顺序却是反的:

<soap:Body>
....
</soap:Body>
<soap:Header>
....
</soap:Header>

按照官方和网络上的一些解决方法是使用@Order注解来手动指定标签的顺序就可以了,像下面这样:

@Root(name = "soap:Envelope")
@Order(elements = {"soap:Header", "soap:Body"})
@NamespaceList({
        @Namespace(reference = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap"),
        @Namespace(reference = "http://www.w3.org/2001/XMLSchema-instance", prefix = "xsi"),
        @Namespace(reference = "http://www.w3.org/2001/XMLSchema", prefix = "xsd")
})
public class DemoRequest {

    @Element(name = "soap:Header")
    public XMLHeader header;

    @Element(name = "soap:Body")
    public XMLBody body;

    // ........
}

但是,这么做对带前缀的标签并不起作用,因为我的标签带有 soap: 前缀,所以并不奏效,这应该是 simplexml 的一个bug吧,总之,如果你的标签不带前缀,使用@Order注解应该是可以的,如果你的标签也带前缀的话,可以用下面的方法来解决:

将需要排序的标签按照 element1、element2....这样的顺序命名即可

@Root(name = "soap:Envelope")
@NamespaceList({
        @Namespace(reference = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap"),
        @Namespace(reference = "http://www.w3.org/2001/XMLSchema-instance", prefix = "xsi"),
        @Namespace(reference = "http://www.w3.org/2001/XMLSchema", prefix = "xsd")
})
public class DemoRequest {

    @Element(name = "soap:Header")
    public XMLHeader element1;

    @Element(name = "soap:Body")
    public XMLBody element2;

    // ........
}

这样,生成的xml参数顺序就是正常的了:

<soap:Header>
....
</soap:Header>
<soap:Body>
....
</soap:Body>
上一篇下一篇

猜你喜欢

热点阅读