axis-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "McCullough, Ryan" <rmccullo...@rightnow.com>
Subject Axis 1.4: element with nillable="true" minOcurrs="0" is omitted when value is null
Date Thu, 04 Dec 2008 18:29:12 GMT
In Axis 1.4 (not Axis2) an element is omitted from the request if the value is set to null
and it is has the nillable="true" and minOccurs="0" attributes set in the schema.

Here is the location where I think things are going wrong:
org.apache.axis.encoding.ser.BeanSerializer.serialize(QName name, Attributes attributes, Object
value, SerializationContext context)

Here is the chunk of code:
// Serialize each property
for (int i=0; i<propertyDescriptor.length; i++) {

      <SNIP>

      // Read the value from the property
      if (propertyDescriptor[i].isReadable()) {
            if (itemQName != null ||
                        (!propertyDescriptor[i].isIndexed() && !isArray)) {
                  // Normal case: serialize the value
                  Object propValue =
                        propertyDescriptor[i].get(value);


                  if (propValue == null) {
                        // an element cannot be null if nillable property is set to
                        // "false" and the element cannot be omitted
                        if (!isNillable && !isOmittable) {
                              if (Number.class.isAssignableFrom(javaType)) {
                                    // If we have a null and it's a number, though,
                                    // we might turn it into the appropriate kind of 0.
                                    // TODO : Should be caching these constructors?
                                    try {
                                          Constructor constructor =
                                                      javaType.getConstructor(
                                                                  SimpleDeserializer.STRING_CLASS);
                                          propValue = constructor.newInstance(ZERO_ARGS);
                                    } catch (Exception e) {
                                          // If anything goes wrong here, oh well we tried.
                                    }
                              }

                              if (propValue == null) {
                                    throw new IOException(
                                                Messages.getMessage(
                                                            "nullNonNillableElement",
                                                            propName));
                              }
                        }

                        // if meta data says minOccurs=0, then we can skip
                        // it if its value is null and we aren't doing SOAP
                        // encoding.
                        if (isOmittable && !isEncoded) { // *** HERE IS THE PROBLEM
I THINK ***
                              continue;
                        }
                  }

                <SNIP>

            } else {

                <SNIP>

            }
      }
}

I snipped some sections of the code to make it easier to see where I think things are going
wrong.

How can I have an element that is nullable but omittable, but I want to explicitly set it
to null. I don't know that I want this to be a global change either.

If it helps, I did modify the soap stub generator to generate an <attrib_name>Specified
Boolean flag in the soap stubs. This flag is set to true when the attribute is set:
public class Street_addr  implements java.io.Serializable, api.rightnow.com.RNOWISpecified
{
    boolean UseSpecified; // Flag to indicate that we are serializing
    private java.lang.String city;
    private boolean citySpecified;
    private java.lang.Integer country_id;
    private boolean country_idSpecified;
    private java.lang.String postal_code;
    private boolean postal_codeSpecified;
    private java.lang.Integer prov_id;
    private boolean prov_idSpecified;
    private java.lang.String street;
    private boolean streetSpecified;
    public Street_addr() {
    }

      <SNIP>

    /**
     * Gets the prov_id value for this Street_addr.
     *
     * @return prov_id
     */
    public java.lang.Integer getProv_id() {
        if (UseSpecified && !prov_idSpecified)
            return null;
        return prov_id;
    }

    /**
     * Sets the prov_id value for this Street_addr.
     *
     * @param prov_id
     */
    public void setProv_id(java.lang.Integer pprov_id) {
        prov_idSpecified=true;
        this.prov_id = pprov_id;
    }


So I could possibly check to see if this flag is set to true before omitting the element.

Thoughts?

-Ryan

Ryan McCullough | RightNow Technologies | Integration Tools Engineer
406-556-3162 office | Bozeman, MT | rmccullough@rightnow.com<mailto:rmccullough@rightnow.com>
| http://www.rightnow.com<http://www.rightnow.com/>


Mime
View raw message