如何在Android上使用的XStream时,注释订单场? [英] How to annotation order field when using XStream on Android?

查看:270
本文介绍了如何在Android上使用的XStream时,注释订单场?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要生成来自于Android的Java对象的XML。 XML节点必须在
明确的序列。下面是我得到了(这些领域按照字母顺序排列):

 <肥皂:信封的xmlns:CWMP =瓮:dslforum-组织:CWMP-1-0
的xmlns:SOAP =htt​​p://schemas.xmlsoap.org/soap/envelope
的xmlns:SOAPENC =htt​​p://schemas.xmlsoap.org/soap/encoding
的xmlns:XSD =htt​​p://www.w3.org/2001/XMLSchema
XMLNS:XSI =htt​​p://www.w3.org/2001/XMLSchema-instance>
  <肥皂:身体与GT;
    < CWMP:通知>
      <&CURRENTTIME GT; 2013年6月7日07:11:20.561 UTC< / CURRENTTIME>
      <&的DeviceID GT;
        <&OUI GT; 002615< / OUI>
        <制造商和GT;与科胜讯LT; /制造商及GT;
        < ProductClass> ADSL2 + IAD< / ProductClass>
        <&的SerialNumber GT; 00261559a496< /&的SerialNumber GT;
      < / DEVICEID>
      <事件SOAPENC:arrayType中=CWMP:EventStruct [1]>
        < EventStruct>
          < CommandKey>< / CommandKey>
          <事件code> 0 Bootstrap与LT; /事件code>
        < / EventStruct>
      < /事件>
      <参数列表SOAPENC:arrayType中=CWMP:ParameterValueStruct [1]>
        < ParameterValueStruct>
          <名称>&InternetGatewayDevice.DeviceInfo.SpecVersion LT; /名称>
          < VALUE> 1.0 LT; /值>
        < / ParameterValueStruct>
      < /参数列表>
      &所述; MaxEnvelopes→1&下; / MaxEnvelopes>
      &所述; RetryCount重大于0&下; / RetryCount重>
    < / CWMP:通知>
  < / SOAP:身体与GT;
  <肥皂:页眉和GT;
    &所述; ID皂:mustUnderstand属性=1>
      <串GT; 00001< /串>
    < / ID>
  < / SOAP:包头>
< / SOAP:信封>

下面就是我想它是:

 <肥皂:信封的xmlns:SOAP =htt​​p://schemas.xmlsoap.org/soap/envelope的xmlns:SOAPENC =htt​​p://schemas.xmlsoap.org / SOAP /编码的xmlns:CWMP =瓮:dslforum-组织:CWMP-1-0的xmlns:XSD =http://www.w3.org/2001/XMLSchema中的xmlns:XSI =HTTP:// www.w3.org/2001/XMLSchema-instance\">
  <肥皂:页眉和GT;
    &所述; ID皂:mustUnderstand属性=1>
      <串GT; 00001< /串>
    < / ID>
  < / SOAP:包头>
  <肥皂:身体与GT;
    < CWMP:通知>
      <&的DeviceID GT;
        <制造商和GT;与科胜讯LT; /制造商及GT;
        <&OUI GT; 002615< / OUI>
        < ProductClass> ADSL2 + IAD< / ProductClass>
        <&的SerialNumber GT; 00261559a496< /&的SerialNumber GT;
      < / DEVICEID>
      <事件SOAPENC:arrayType中=CWMP:EventStruct [1]>
        < EventStruct>
          <事件code> 0 Bootstrap与LT; /事件code>
          < CommandKey>< / CommandKey>
        < / EventStruct>
      < /事件>
      &所述; MaxEnvelopes大于0&下; / MaxEnvelopes>
      <&CURRENTTIME GT; 2013年6月7日07:16:54.128 UTC< / CURRENTTIME>
      &所述; RetryCount重大于0&下; / RetryCount重>
      <参数列表SOAPENC:arrayType中=CWMP:ParameterValueStruct [1]>
        < ParameterValueStruct>
          <名称>&InternetGatewayDevice.DeviceInfo.SpecVersion LT; /名称>
          < VALUE> 1.0 LT; /值>
        < / ParameterValueStruct>
      < /参数列表>
    < / CWMP:通知>
  < / SOAP:身体与GT;
< / SOAP:信封>

我已经调查了此问题的更多。而且我发现,西河处理领域中
错误的命令在Android上。西河处理场以及在Java项目。

  @XStreamAlias​​(CWMP:通知)
公共类通知{
    @XStreamAlias​​(DEVICEID)
    私人DeviceIdStruct DEVICEID;    @XStreamAlias​​(事件)
    私人EVENTLIST事件;    @XStreamAlias​​(MaxEnvelopes)
    私人诠释maxEnvelopes;    @XStreamAlias​​(CURRENTTIME)
    私人日期currentTime的;    @XStreamAlias​​(RetryCount重)
    私人诠释RetryCount重;    @XStreamAlias​​(参数列表)
    私人ParameterValueList PARAMETERLIST;
}


解决方案

<一个href=\"http://xstream.10960.n7.nabble.com/Is-there-a-way-to-set-the-order-of-Xstream-serialization-tp8300p8464.html\"相对=nofollow>这里是我的答案。
结果我研究这个问题,并得出结论认为,Android的返回字段类型的字母顺序领域。
您可以继承FieldKeySorter设置顺序。

首先,你需要创建注释,将定义字段顺序:

  @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
公共@interface XMLSequence {
    字符串值();
}

例如,使用

  @XMLSequence({
        accountIds
        地址,
        生日,
        联系,
        名称,
        状态,
})

然后我继承FieldKeySorter:

 公共类SequenceFieldKeySorter实现FieldKeySorter {
    @覆盖
    公共地图排序(final类类型,最终地图keyedByFieldKey){
        注释序列= type.getAnnotation(XMLSequence.class);
        如果(序列!= NULL){
            最终的String [] fieldsOrder =((XMLSequence)序列).value的();
            地图结果=新OrderRetainingMap();
            SET&LT;&Map.Entry的LT; FieldKey,场及GT;&GT;域= keyedByFieldKey.entrySet();
            对于(字符串fieldName的:fieldsOrder){
                如果(字段名!= NULL){
                    对于(Map.Entry的&LT; FieldKey,现场&GT; fieldEntry:字段){
                        如果
(fieldName.equals(fieldEntry.getKey()。getFieldName())){
                            result.put(fieldEntry.getKey(),
fieldEntry.getValue());
                        }
                    }
                }
            }
            返回结果;
        }其他{
            返回keyedByFieldKey;
        }    }
}

最后去:

  XStream的X =新的XStream(新PureJavaReflectionProvider(
新FieldDictionary(新SequenceFieldKeySorter())));

I need to generate XML from java objects on Android. XML nodes must be in definite sequence. Here is what I got(These fields as according to alphabetical order):

<soap:Envelope xmlns:cwmp="urn:dslforum-org:cwmp-1-0" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <cwmp:Inform>
      <CurrentTime>2013-06-07 07:11:20.561 UTC</CurrentTime>
      <DeviceId>
        <OUI>002615</OUI>
        <Manufacturer>Conexant</Manufacturer>
        <ProductClass>ADSL2+ IAD</ProductClass>
        <SerialNumber>00261559a496</SerialNumber>
      </DeviceId>
      <Event soapenc:arrayType="cwmp:EventStruct[1]">
        <EventStruct>
          <CommandKey></CommandKey>
          <EventCode>0 BOOTSTRAP</EventCode>
        </EventStruct>
      </Event>
      <ParameterList soapenc:arrayType="cwmp:ParameterValueStruct[1]">
        <ParameterValueStruct>
          <name>InternetGatewayDevice.DeviceInfo.SpecVersion</name>
          <value>1.0</value>
        </ParameterValueStruct>
      </ParameterList>
      <MaxEnvelopes>1</MaxEnvelopes>
      <RetryCount>0</RetryCount>
    </cwmp:Inform>
  </soap:Body>
  <soap:Header>
    <ID soap:mustUnderstand="1">
      <string>00001</string>
    </ID>
  </soap:Header>
</soap:Envelope>

Here is what I want it to be:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding" xmlns:cwmp="urn:dslforum-org:cwmp-1-0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Header>
    <ID soap:mustUnderstand="1">
      <string>00001</string>
    </ID>
  </soap:Header>
  <soap:Body>
    <cwmp:Inform>
      <DeviceId>
        <Manufacturer>Conexant</Manufacturer>
        <OUI>002615</OUI>
        <ProductClass>ADSL2+ IAD</ProductClass>
        <SerialNumber>00261559a496</SerialNumber>
      </DeviceId>
      <Event soapenc:arrayType="cwmp:EventStruct[1]">
        <EventStruct>
          <EventCode>0 BOOTSTRAP</EventCode>
          <CommandKey></CommandKey>
        </EventStruct>
      </Event>
      <MaxEnvelopes>0</MaxEnvelopes>
      <CurrentTime>2013-06-07 07:16:54.128 UTC</CurrentTime>
      <RetryCount>0</RetryCount>
      <ParameterList soapenc:arrayType="cwmp:ParameterValueStruct[1]">
        <ParameterValueStruct>
          <name>InternetGatewayDevice.DeviceInfo.SpecVersion</name>
          <value>1.0</value>
        </ParameterValueStruct>
      </ParameterList>
    </cwmp:Inform>
  </soap:Body>
</soap:Envelope>

I've investigated this problem more. And I found that Xstream handles fields in wrong order on Android. Xstream handles fields well in Java project.

@XStreamAlias("cwmp:Inform")
public class Inform {
    @XStreamAlias("DeviceId")
    private DeviceIdStruct      deviceId;

    @XStreamAlias("Event")
    private EventList           event;

    @XStreamAlias("MaxEnvelopes")
    private int                 maxEnvelopes;

    @XStreamAlias("CurrentTime")
    private Date                currentTime;

    @XStreamAlias("RetryCount")
    private int                 retryCount;

    @XStreamAlias("ParameterList")
    private ParameterValueList  parameterList;
}

解决方案

Here is my answer.
I researched the issue and concluded that Android returns fields in alphabetical order of field types. You can inherit FieldKeySorter to set order.

First you need create annotation that will define fields order:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface XMLSequence {
    String[] value();
} 

And example using:

@XMLSequence({
        "accountIds",
        "addresses",
        "birthDate",
        "contact",
        "name",
        "status",
}) 

Then I've inherited FieldKeySorter :

public class SequenceFieldKeySorter implements FieldKeySorter {
    @Override
    public Map sort(final Class type, final Map keyedByFieldKey) {
        Annotation sequence = type.getAnnotation(XMLSequence.class);
        if (sequence != null) {
            final String[] fieldsOrder = ((XMLSequence) sequence).value();
            Map result = new OrderRetainingMap();
            Set<Map.Entry<FieldKey, Field>> fields = keyedByFieldKey.entrySet();
            for (String fieldName : fieldsOrder) {
                if (fieldName != null) {
                    for (Map.Entry<FieldKey, Field> fieldEntry : fields) {
                        if
(fieldName.equals(fieldEntry.getKey().getFieldName())) {
                            result.put(fieldEntry.getKey(),
fieldEntry.getValue());
                        }
                    }
                }
            }
            return result;
        } else {
            return keyedByFieldKey;
        }

    }
}

And finally go:

XStream x = new XStream(new PureJavaReflectionProvider(
new FieldDictionary(new SequenceFieldKeySorter()))); 

这篇关于如何在Android上使用的XStream时,注释订单场?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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