@Order 注释对 XML 序列化顺序没有影响

@Order annotation has no effect on the XML serialization order

我正在使用带有 SimpleXmlConverter 的 Retrofit 2,我在创建 Soap 请求对象时遇到了一个问题,它基本上是一个具有 4 个子元素的元素,每个子元素都是不同的数据类型。

这是我想要生成的 XML 输出。必须遵守元素顺序:

 <prf:container>
    <prf:aaa>111111111</prf:aaa>
    <prf:bbb>true</prf:bbb>
    <prf:element>
        <prf:ddd>50</prf:ddd>
        <prf:eee>false</prf:eee>
    </prf:element>
    <prf:ccc>textcontent</prf:ccc>
</prf:container>

现在,这是我的 Android Class、Container.java,表示将被序列化的 Soap 请求对象:

@Root (name = "prf:container")
@Order(elements={"prf:aaa", "prf:bbb", "prf:element", "prf:ccc"})
public class Container {

    @Element (name = "prf:aaa")
    private int aaa;

    @Element(name = "prf:bbb")
    private boolean bbb;

    @Element (name = "prf:element", required = false)
    private MyElement myElement;

    @Element (name = "prf:ccc", required = false)
    private String ccc;

}

根据 Simple XML 框架文档:

By default serialization of fields is done in declaration order.

然而,在Android中,这不是真的,至少在某些情况下是这样。无论我如何在 Container class 中设置字段声明顺序,输出始终具有相同的元素顺序。这是一个已知错误,正如其他 SO 帖子中所报告的那样。

尽管如此,这个问题还是有解决办法的。 Order 注释。 阅读更多 in the Javadoc.

我的问题是在我的案例中使用 Order 注释没有帮助。请注意,我所有的元素在其名称上都有一个前缀 - prf:.

如果我从所有元素名称中删除 prf 前缀,Order 注释将正常工作,并强制 XML 序列化具有定义的顺序。但是输出元素的名称上没有前缀。

但我真的需要我的元素在其名称上有前缀,否则我的请求将得到 500 响应。我还必须在 XML 输出中包含所需的元素顺序。

有什么解决办法吗?

谢谢

我知道自从您发布此问题以来已经过了很久,但是,我想回答您的问题,以防有人遇到同样的问题。我通过执行以下操作解决了同样的问题:

对于要按照您想要的顺序使用元素准备的 XML 文档,如果元素有前缀,@Order 注释在某些情况下可能不起作用。在您的情况下,每个元素的 @Order 注释中提到的前缀 'prf' 将无法按照您的需要对它们进行排序。

"By default serialization of fields is done in declaration order."

我也不相信,尤其是当你有元素前缀的时候。因此,我尝试更改 Java 变量名称。我尝试按照我在生成的 xml 中需要它们的方式按字母顺序命名它们。因此,在您的情况下,您可以按如下方式更改变量名称:

@Root (name = "prf:container")
public class Container {

    @Element (name = "prf:aaa")
    private int element1;

    @Element(name = "prf:bbb")
    private boolean element2;

    @Element (name = "prf:element", required = false)
    private MyElement element3;

    @Element (name = "prf:ccc", required = false)
    private String element4;

}

这将形成您想要的 xml 文档。您可能想知道,如果我们将变量名称更改得过于通用,它们并不能代表它们实际的含义,但是您始终可以使用 getter 和 setter。例如,在您的情况下,您可以:

public void setAaa(String aaa){
    this.element1 = aaa;
}

public String getAaa(){
    return element1;
}

以相同的方式,您始终可以生成具有按字母顺序排列的变量的 类,以确保生成的 xml 具有所需格式的元素。

可能您使用@O​​rder 的语法错误,字母顺序并不重要。你可以试试:

@Root (name = "prf:container")
@Order(elements={"prf:container/prf:aaa", "prf:container/prf:bbb", "prf:container/prf:element", "prf:container/prf:ccc"})
public class Container {

    @Element (name = "prf:aaa")
    private int aaa;

    @Element(name = "prf:bbb")
    private boolean bbb;

    @Element (name = "prf:element", required = false)
    private MyElement myElement;

    @Element (name = "prf:ccc", required = false)
    private String ccc;
}

SimpleXML 的按字母顺序自动排序功能正常。但有一个条件:这些字段的类型应该相同,通常 XML 是 String。我花了很长时间才弄明白,我有不同的类型,按名字排序是行不通的。由于我已将所有字段更改为字符串,所以效果很好。

@Root(name = "sch:CheckPaymentRequest", strict = true)
public class CheckPaymentData {

@Element(name = "sch:payId")
private String Aaa1;

@Element(name = "sch:fromCurrency")
private String Bbb2;

@Element(name = "sch:fromAmount")
private String Ccc3;
...}