@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 具有所需格式的元素。
可能您使用@Order 的语法错误,字母顺序并不重要。你可以试试:
@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;
...}
我正在使用带有 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 具有所需格式的元素。
可能您使用@Order 的语法错误,字母顺序并不重要。你可以试试:
@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;
...}