Search code examples
cxfapache-axisadbwebservice-client

Request server using Axis2 RPC way, parameter order in xml packets not correct


For example, I will send an object Fruits to server side.

The code like this:

public static <T> T call(String url, String ns, String method, Fruits fruits, Class<T> clz) throws AxisFault
{
  RPCServiceClient client = new RPCServiceClient();
  Options option = client.getOptions();
  EndpointReference erf = new EndpointReference(url);
  option.setTo(erf);
  QName name = new QName(ns, method);
  Object[] object = new Object[]{fruits};
  Class[] returnTypes = new Class[]{clz};
  Object[] reto = client.invokeBlocking(name, object, returnTypes);
  T t = (T)reto[0];
  return t;
}

The object like this:

public class Fruits implements Serializable
{
  private int pear;
  private int banana;
  private int apple;

  public int setPear(int pear){this.pear=pear;}
  public int getPear(){return this.pear;}
  ...
}

The xml part should be this:

...
<fruits>
  <pear>10</pear>
  <banana>20</banana>
  <apple>60</apple>
</fruits>
...

But in fact like this:

...
<fruits>
  <apple>60</apple>
  <banana>20</banana>
  <pear>10</pear>
</fruits>
...

Axis2 makes object's property alphabetical order, but the server doesn't accept. I can't modify the serverside, it is ESB.

The only way to do a success request is to use the Axis2 generated code, I used to use WSDL2Java, but too many redundant code and difficult to maintain. So I want refactor.

I have also tried to use CXF, but it also makes object's property alphabetical order, not followed with WSDL/XSD or DTO defined style.

I've find the reason why CXF makes the ordering, it uses java.beans.BeanInfo to get properties of object, such as:

...
BeanInfo beanInfo = Introspector.getBeanInfo(Fruits.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
...

The property in the array has already alphabetical order.

Who knows how to let Axis2 to serialize the Fruits' property to be correct ordering.

Thank you, the first!


Solution

  • Not sure on Axis2, but if you are using CXF with the JAXB databinding, you can add an annotation like:

    @XmlType(name = "fruits", propOrder = { "apple", "banana", "pear" }})
    

    to the Fruits class to tell JAXB what order you need/want them output.