Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Order annotation has no effect on the XML serialization order

I'm using Retrofit 2 with a SimpleXmlConverter and I am facing an issue when creating a Soap Request Object, that is basically an element with 4 element children each one of them being different datatypes.

Here is the XML output I want to produce. The element order must be respected:

 <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>

Now, here is my Android Class, Container.java, representing the Soap Request Object that will be serialized:

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

}

According to the Simple XML framework documentation:

By default serialization of fields is done in declaration order.

However, in Android, this is not true, at least in some cases. No matter how I set the field declaration order in my Container class, the output has always the same element order. This is a known bug and as has been reported in other SO posts.

Nonetheless, there is a solution to this issue. The Order annotation. Read more in the Javadoc.

My problem is that using the Order annotation in my case is not helping. Note that all my elements have a prefix on its name - prf:.

If I remove the prf prefix from all my element names, Order annotation will work properly, and force the XML Serialization to have the defined order. But the output elements won't have the prefix on its name.

But I really need my elements to have the prefix on its name, or else my request will have a 500 response. I also have to have the desired element order in my XML output.

Any solution to this?

Thank you

like image 220
joao2fast4u Avatar asked Sep 25 '22 09:09

joao2fast4u


1 Answers

I know it has been a long item since you posted this question but, I would like to answer your question in case anyone faced the same issue. I solved the same issue by doing the following:

For the XML document to be prepared with the elements in the order you want and if the elements have a prefix, @Order annotation might not work in some cases. In your case, the prefix 'prf' mentioned in the @Order annotation for each element would not work to order them as you desired.

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

I don't believe this either, especially when you have prefixes for elements. So, I tried changing the Java variable names. I tried naming them in alphabetical order in the same way I needed them in the generated xml. So, in your case, you can change the variable names as follows:

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

}

This would form the xml document exactly as you wanted. You might wonder that if we change the variable names to be too generic, they are not representing what they actually are but, you can always have getters and setters. For example, in your case you can have:

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

public String getAaa(){
    return element1;
}

In the same way you can always generate the classes with alphabetically ordered variables to make sure the generated xml has the elements in the desired format.

like image 97
zilwood Avatar answered Oct 02 '22 10:10

zilwood