Hi Andy,

This is the way we do it using Aegis.

1) setup our Type Mapping Registry and add a Configuration to it like this:

   <bean id="webAnnotations"
class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" />
   <bean id="handlerMapping"
       class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping"
       autowire="no">
       <property name="typeMappingRegistry">
           <ref bean="typeMappingRegistry" />
       </property>
       <property name="xfire">
           <ref bean="xfire" />
       </property>
       <property name="webAnnotations">
           <ref bean="webAnnotations" />
       </property>
   </bean>
   <bean id="typeConfig"
       class="org.codehaus.xfire.aegis.type.Configuration">
       <property name="defaultExtensibleElements" value="true" />
       <property name="defaultExtensibleAttributes" value="true" />
       <property name="defaultNillable" value="false" />
       <property name="defaultMinOccurs" value="1" />
   </bean>
   <bean id="typeMappingRegistry"
       class="com.xmltravel.fab.core.types.aegis.FABTypeMappingRegistry">
       <property name="configuration">
           <ref bean="typeConfig" />
       </property>
   </bean>

FABTypeMappingRegistry just inherits from org.codehaus.xfire.aegis.type.DefaultTypeMappingRegistry and adds a few custom types for dateTime handling.

The key here is:

       <property name="defaultExtensibleElements" value="true" />
       <property name="defaultExtensibleAttributes" value="true" />

Which will mean that your resulting WSDL will contain complex types like this:

<xsd:complexType name="ResponseHeader">
   <xsd:sequence>
       <xsd:element name="target" type="ns2:Target"/>
       <xsd:element name="timingInfo" type="ns7:TimingInfo"/>
       <xsd:element name="trackingInfo" type="ns7:TrackingInfo"/>
       <xsd:element name="userInfo" type="ns7:UserInfo"/>
       <xsd:any maxOccurs="unbounded" minOccurs="0"/>
   </xsd:sequence>
   <xsd:anyAttribute/>
</xsd:complexType>

which include extra tags <xsd:any maxOccurs="unbounded" minOccurs="0"/> and <xsd:anyAttribute/> which means that any extra content will also not break the schema. When Axis build against this then it will accept things it doesn't recognise and store them in extra data structures.

2) As this will effect ALL classes converted via Aegis we also want to lock down what users can send in. So we add the following annotations to all request only classes (i.e. Classes that only ever occur within request structures and can't possibly be returned to the clients):

@XmlType(extensibleAttributes=false, extensibleElements=false)
public class TrackingInfo extends com.xmltravel.fab.core.response.TrackingInfo
{
// blah
}

This will supress the extra elements being added to the WSDL schema and prevent clients sending in anything they like.

I hope this helps you out.

Cheers,

Adam Chesney

Lead Architect
Multicom Products Ltd


Andy Gelfond wrote:
We use xfire to provide a service to a number of clients. We have found that by simply adding a new field to an object, some of our clients break.

Clients who do not recompile their code based on the new wsdl will break if they are using axis:
http://www.ncbi.nlm.nih.gov/entrez/query/static/esoap_help.html

We generate our wsdl based on our code, and it seems we generate our return datastream based on the code also. Is there a simple workaround using xfire ?
Thanks in advance,
Andy

Reply via email to