For CXF up to 2.0.x
Why Aegis?
Aegis is a fast, StAX based, data-binding that makes developing code first services as simply as possible. It is able to handle most classes and create intelligent schemas for them.
Features include:
- No annotations are needed to expose classes
- Support for interfaces
- Support for collections including Maps
- Support for a wide variety of datatypes
CXF 2.1 Documentation
There are some significant changes to Aegis in CXF 2.1. See Aegis (2.1).
Details on How It Works
This Page, which is a work in progress, explains some of the modularity of Aegis. You may find it helpful in understanding Aegis' behavior and in developing customizations.
Using Aegis
Most people who use Aegis use the Simple Front End. If you are using Aegis, you can't move your code to some other web service framework without modifying all your code to work with JAXB or some other binding, so there's not much advantage to using the JAX-WS front-end. You might want to use Aegis with one of the specialized frontends, like JAX-RS. We don't have examples of that in this documentation.
Spring Configuration
Most people who use Aegis use the 'Simple' front end.
<simple:server id="pojoservice" serviceClass="demo.hw.server.HelloWorld" address="/hello_world">
<simple:serviceBean>
<bean class="demo.hw.server.HelloWorldImpl" />
</simple:serviceBean>
<simple:dataBinding>
<bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
</simple:dataBinding>
<!-- Use this property only for XFire compatibility -- this version for 2.0.x ...
<property name="serviceConfigurations">
<list>
<bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/>
<bean class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration"/>
<bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/>
</list>
</property>
-->
</simple:server>
</bean>
You can also use Aegis with JAX-WS. Here's a Spring configuration example for that.
<bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" scope="prototype"/>
<bean id="jaxws-and-aegis-service-factory"
class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"
scope="prototype">
<property name="dataBinding" ref="aegisBean"/>
<!-- Use this property only for XFire compatibility -- this version for 2.0.x ...
<property name="serviceConfigurations">
<list>
<bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/>
<bean class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration"/>
<bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/>
</list>
</property>
-->
<!-- Use this property only for XFire compatibility -- this version for 2.1
<property name="serviceConfigurations">
<list>
<bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/>
<bean class="org.apache.cxf.aegis.databinding.XFireCompatibilityServiceConfiguration"/>
<bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/>
</list>
</property>
-->
</bean>
<jaxws:endpoint id="my_service_endpoint" implementor="#my-service" address="/MyIndex">
<jaxws:serviceFactory>
<ref bean='jaxws-and-aegis-service-factory' />
</jaxws:serviceFactory>
</jaxws:endpoint>
Java configuration
Here's a Java configuration using the Simple front end.
import org.apache.cxf.aegis.databinding.AegisDatabinding;
import org.apache.cxf.frontend.ServerFactoryBean;
ServerFactoryBean sf = new ServerFactoryBean();
sf.setServiceClass(serviceClass);
sf.setAddress("http:);
sf.getServiceFactory().setDataBinding(new AegisDatabinding());
sf.create();
Similarly, here is a client side using the simple front end. Note the use of the WSDL. Without the WSDL, the simple front end will try to learn
parameters names from Java reflection. As always, Java interfaces don't carry parameter names, and this results in names like 'arg0', 'arg1', etc, which don't match the service.
import org.apache.cxf.aegis.databinding.AegisDatabinding;
import org.apache.cxf.frontend.ClientProxyFactoryBean;
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setServiceClass(serviceInterfaceClassObject);
factory.setAddress("http:);
factory.setWsdlLocation("http:);
factory.getServiceFactory().setDataBinding(new AegisDatabinding());
MyService client = (MyService) factory.create();
XFire Compatibility
XFire had/has a different convention for generating namespace URI values from Java package names. It added an additional '/' character.
If you need to interoperate with XFire, you need to enable compatibility with this behavior. You enable this compatibility by adding
an additional service configuration class to your service configuration: XFireCompatibilityServiceConfiguration (in 2.0.x, AegisServiceConfiguration).
The spring example above shows the necessary configuration in a comment. For the client side in Java, you need to add the service configuration to the service factory
as follows:
import org.apache.cxf.aegis.databinding.AegisServiceConfiguration;
sf.getServiceFactory().getServiceConfigurations().add(0, new AegisServiceConfiguration());
sf.getServiceFactory().getServiceConfigurations().add(0, new XFireCompatibilityServiceConfiguration());
This will the change the namespaces that CXF generates by default so that they are the same as XFire would generate.
Class <-> XML Mapping Overview
Aegis has a flexible mapping system so you can control how your beans are controlled. By default your POJOs are serialized based on their name and namespaces. If you have a class in the "org.codehaus.xfire" package named "Employee" it would be serialized in namespace "http://xfire.codehaus.org" with the local name "Employee"
Fore example, the java class:
public class Employee
{
private String name;
private String title;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
}
In XML this translates to:
<Employee xmlns="http://xfire.codehaus.org">
<name>Santa Claus</name>
<title>Chief Present Officer (CPO)</title>
</Employee>
In XML Schema this would become a complex type:
<xsd:complexType name="Employee">
<xsd:sequence>
<xsd:element name="name" type="xsd:string" minOccurs="0" maxOccurs="1/>
<xsd:element name="title" type="xsd:string" minOccurs="0" maxOccurs="1/>
</xsd:sequence>
</xsd:complexType>
| Validate your mapping!
You can find an XML Schema for Aegis mapping files here.
This version of the XML schema has comments to explain the bits and pieces. |
Supported Types
- Basic types: int, double, float, long, byte[], short, String, BigDecimal
- Arrays
- Collections - including Maps
- Dates: java.util.Date, java.util.Calendar, java.sql.Timestamp, java.sql.Date, java.sql.Time
- XML: org.w3c.dom.Docmument, org.jdom.Element, XMLStreamReader, Source
- Complex types which are aggregations of the above
If you have constructors defined in your Java beans, make sure a default constructor (i.e. no arguments) is also declared. (Aegis needs a no-argument contstructor to instantiate client Java classes.)
Setting Default minOccurs and nillable Parameters from Java
If you have many properties, and you want most, or all of them, to have a minOccurs other than 0 or a nillable other than false, you can change the defaults for Aegis from Java code (amongst other places).
Here is an example: it extracts the binding provider from the service factory, and changes the configuration parameters.
ServerFactoryBean sf = new ServerFactoryBean();
sf.setServiceClass(serviceClass);
sf.setAddress("http:);
AegisDatabinding db = new AegisDatabinding();
sf.getServiceFactory().setDataBinding(db);
DefaultTypeMappingRegistry tmr = (DefaultTypeMappingRegistry)db.getTypeMappingRegistry();
Configuration configuration = tmr.getConfiguration();
configuration.setDefaultMinOccurs(1);
configuration.setDefaultNillable(false);
sf.create();
More Information....
This section is under construction. For more information about how the Aegis databinding works, please check out the Aegis documentation at the XFire site.