XFireHome DocumentationJavadocs QuicklinksAegis Binding DevelopersDeveloper Space |
This tutorial offers a 7-step approach to creating XFire web services that utilize JSR 181 annotations and Apache XMLBeans. Step 1: DependenciesSample IVY Config FileOne of the first steps in getting XFire working is simply setting up the initial JAR dependencies. For those of you already familiar with maven or ivy, this dependency list below should look familiar. While there may be a few extra JAR files listed below that are not required to use XFire, the overall list and JAR revisions should help you get started. Check the XFire dependency guide for more information.
<dependencies> <!-- WEBAPP Jars --> <dependency org="log4j" name="log4j" rev="1.2.9" conf="bundle,runtime->default" /> <dependency org="springframework" name="springframework" rev="1.2.6" conf="bundle,runtime->default"> <artifact name="spring" type="jar"/> </dependency> <dependency org="commons-codec" name="commons-codec" rev="1.3" conf="client,bundle,runtime->default" /> <dependency org="commons-beanutils" name="commons-beanutils" rev="1.7.0" conf="bundle,runtime->default" /> <dependency org="commons-collections" name="commons-collections" rev="2.1" conf="bundle,runtime->default" /> <dependency org="commons-digester" name="commons-digester" rev="1.5" conf="bundle,runtime->default" /> <dependency org="commons-discovery" name="commons-discovery" rev="0.2" conf="bundle,runtime->default" /> <dependency org="commons-httpclient" name="commons-httpclient" rev="3.0" conf="client,bundle,runtime->default" /> <dependency org="commons-el" name="commons-el" rev="1.0" conf="bundle,runtime->default" /> <dependency org="commons-fileupload" name="commons-fileupload" rev="1.0" conf="bundle,runtime->default" /> <dependency org="commons-logging" name="commons-logging" rev="1.0.4" conf="client,bundle,runtime->default" /> <dependency org="commons-validator" name="commons-validator" rev="1.1.4" conf="bundle,runtime->default" /> <dependency org="oro" name="oro" rev="2.0.8" conf="bundle,runtime->default" /> <dependency org="jstl" name="jstl" rev="1.1.2" conf="bundle,runtime->default" /> <dependency org="javamail" name="mailapi" rev="1.3.2" conf="client,bundle,runtime->default" /> <dependency org="xbean" name="xbean-spring" rev="2.0" conf="bundle,runtime->default" /> <dependency org="jaxen" name="jaxen" rev="1.1-beta-8" conf="bundle,runtime->default" /> <dependency org="jdom" name="jdom" rev="1.0" conf="client,bundle,runtime->default" /> <dependency org="wsdl4j" name="wsdl4j" rev="1.4" conf="client,bundle,runtime->default" /> <!-- Stax is the XML api that powers XFire and allows it to process XML efficiently. There are many different Atax implementations out there - the reference implementation (RI), Woodstox, FastInfoset, and there is one included in the JWSDP. Regardless of which you one choose you must have the stax-api jar on your classpath. In addition we highly recommend that you use Woodstox as your Stax implementation. It is about 30-40% faster then the RI and works more reliably. To ensure you are using Woodstox and not the RI make sure the stax-1.1.x-dev jar is off your classpath and the wstx-2.0.3 jar is on it. <dependency org="wstx" name="wstx" rev="2.0.3" conf="bundle,runtime->default" /> --> <dependency org="woodstox" name="wstx-lgpl" rev="2.8" conf="client,bundle,runtime->default" /> <dependency org="stax" name="stax" rev="api-1.0" conf="client,bundle,runtime->default" /> <dependency org="xfire" name="xfire-all" rev="1.0-SNAPSHOT" conf="client,bundle,runtime->default" /> <dependency org="acegisecurity" name="acegisecurity" rev="0.9.0" conf="bundle,runtime->default"> <artifact name="acegi-security" type="jar" /> </dependency> <dependency org="xfire" name="xfire-jsr181-api" rev="1.0-M1" conf="bundle,runtime->default" /> <dependency org="xfire" name="jaxb-api" rev="20051106" conf="bundle,runtime->default" /> <dependency org="xfire" name="jaxb-impl" rev="20051106" conf="bundle,runtime->default" /> <dependency org="xfire" name="jaxb-xjc" rev="20051106" conf="bundle,runtime->default" /> <dependency org="xfire" name="XmlSchema" rev="20051110" conf="bundle,runtime->default" /> <dependency org="activation" name="activation" rev="1.0.2" conf="client,bundle,runtime->default" /> <dependency org="xmlbeans" name="xmlpublic" rev="2.1.0" conf="client,bundle,runtime->default" /> <dependency org="xmlbeans" name="xbean" rev="2.1.0" conf="client,bundle,runtime->default" /> <dependency org="xmlbeans" name="xbean_xpath" rev="2.1.0" conf="bundle,runtime->default" /> </dependencies> Step 2: Start with XSDIf you subscribe to XML-driven development or MDA or AMDD, then I recommend starting your application with (3) XSD files:
Below are some instructions outlining the intent behind creating these (3) separate XSD files, which are used to then generate XMLBeans in Step 3 of this process.
Step 3: Generate XMLBeansIf your XSDs are placed in META-INF/xfire/, then the following Ant task will generate XMLBeans from the XSD files:
Step 4: Setup Eclipse to Support Annotations
Step 5: Create your annotated service
Step 6: Wire up SpringIf you notice in the ServiceImpl class above, I'm using Spring to do some dependency injection. If you want to do this (sharing your XFire application context with the Spring application context loaded by your web application's org.springframework.web.context.ContextLoaderListener for example, then strip out everything from META-INF/xfire/services.xml and put it in your own Spring config file loaded by the ContextLoaderListener declared in your web application. In your WEB-INF/web.xml, load Spring like this (using the classpath: notation in order to load xfire.xml from your XFire JAR deployed in WEB-INF/lib) <!-- context parameters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/MyService-acegi-base.xml /WEB-INF/MyService-authentication.xml /WEB-INF/MyService-authorization.xml /WEB-INF/MyService-dao.xml /WEB-INF/MyService-sqlmap.xml /WEB-INF/MyService-datasource.xml /WEB-INF/MyService-servlet.xml /WEB-INF/MyService-xfire.xml classpath:org/codehaus/xfire/spring/xfire.xml </param-value> </context-param> <!-- listeners --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> Then declare your XFire spring beans in another Spring XML config file (such as the /WEB-INF/MyService-xfire.xml referenced above). <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- ============================================ --> <!-- Simple Web Service --> <!-- ============================================ --> <bean id="BookService" class="org.codehaus.xfire.spring.ServiceBean" > <property name="serviceClass" value="org.codehaus.xfire.demo.BookService"/> <property name="namespace" value="http://xfire.codehaus.org/BookService"/> </bean> <!-- ============================================ --> <!-- Illustration of simple service using --> <!-- JSR 181 annotations --> <!-- ============================================ --> <bean id="CustomerService" class="org.codehaus.xfire.spring.ServiceBean" > <property name="serviceClass" value="org.codehaus.xfire.demo.CustomerService"/> <property name="serviceFactory" value="jsr181"/> </bean> <!-- ============================================ --> <!-- BASIC BEAN DEFINITIONS --> <!-- ============================================ --> <bean id="webService" class="org.company.service.server.ServiceImpl"> <property name="xyzService" ref="xyzService"/> </bean> <!-- ============================================ --> <!-- FACTORIES --> <!-- ============================================ --> <bean name="xfire.jaxbServiceFactory" class="org.codehaus.xfire.jaxb2.JaxbServiceFactory"> <constructor-arg ref="xfire.transportManager"/> </bean> <bean id="xfire.xmlbeansServiceFactory" class="org.codehaus.xfire.xmlbeans.XmlBeansServiceFactory" singleton="true"> <constructor-arg index="0" ref="xfire.transportManager"/> </bean> <bean id="xfire.annotationServiceFactory" class="org.codehaus.xfire.annotations.AnnotationServiceFactory"> <constructor-arg index="0" ref="webAnnotations"/> <constructor-arg index="1" ref="xfire.transportManager"/> <constructor-arg index="2" ref="xfire.aegisBindingProvider"/> </bean> <bean id="xfire.xmlBeansAnnotationServiceFactory" class="org.codehaus.xfire.annotations.AnnotationServiceFactory"> <constructor-arg index="0" ref="webAnnotations"/> <!-- WebAnnotations --> <constructor-arg index="1" ref="xfire.transportManager"/> <!-- TransportManager --> <constructor-arg index="2" ref="xmlbeans.aegisBindingProvider"/> <!-- BindingProvider --> </bean> <!-- ============================================ --> <!-- REGISTRIES + PROVIDERS --> <!-- ============================================ --> <bean id="xmlbeansTypeRegistry" class="org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry"/> <bean id="xmlbeans.aegisBindingProvider" class="org.codehaus.xfire.aegis.AegisBindingProvider"> <constructor-arg index="0" ref="xmlbeansTypeRegistry"/> </bean> <!-- ============================================ --> <!-- ANNOTATION FACADES --> <!-- ============================================ --> <bean id="webAnnotations" class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"/> <!-- ============================================ --> <!-- WEB SERVICE TEMPLATES --> <!-- ============================================ --> <bean id="xfireServiceTemplate" class="org.codehaus.xfire.spring.remoting.XFireExporter" abstract="true"> <property name="serviceFactory" ref="xfire.serviceFactory" /> <property name="xfire" ref="xfire" /> <property name="style" value="document" /> <property name="use" value="literal" /> </bean> <bean id="xfireXMLBeansServiceTemplate" class="org.codehaus.xfire.spring.remoting.XFireExporter" abstract="true"> <property name="serviceFactory" ref="xfire.xmlbeansServiceFactory" /> <property name="xfire" ref="xfire" /> <property name="style" value="document" /> <property name="use" value="literal" /> </bean> <bean id="xfireXMLBeansAnnotationsServiceTemplate" class="org.codehaus.xfire.spring.remoting.XFireExporter" abstract="true"> <property name="serviceFactory" ref="xfire.xmlBeansAnnotationServiceFactory" /> <property name="xfire" ref="xfire" /> <property name="style" value="document" /> <property name="use" value="literal" /> </bean> <!-- ============================================ --> <!-- EXPORTED SERVICES --> <!-- ============================================ --> <bean id="MyXFireService" parent="xfireXMLBeansAnnotationsServiceTemplate" > <property name="serviceBean" ref="webService"/> <!-- Interface specification is no longer required when using xfire-jsr181-api-1.0-M1.jar instead of wsm-1.0-alpha.jar <property name="serviceInterface" value="org.company.service.server.ServiceInterface"/> --> <property name="schemas"> <list> <value>/META-INF/xfire/Common.xsd</value> <value>/META-INF/xfire/Request.xsd</value> <value>/META-INF/xfire/Response.xsd</value> </list> </property> </bean> Step 7: Deploy the Web Service & Generate the Client
The generated client code will look something like this: package org.company.service.wsclient; import java.net.MalformedURLException; import javax.xml.namespace.QName; import org.codehaus.xfire.XFireRuntimeException; import org.codehaus.xfire.aegis.AegisBindingProvider; import org.codehaus.xfire.annotations.AnnotationServiceFactory; import org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations; import org.codehaus.xfire.client.XFireProxyFactory; import org.codehaus.xfire.service.Endpoint; import org.codehaus.xfire.service.Service; import org.codehaus.xfire.soap.AbstractSoapBinding; import org.codehaus.xfire.transport.TransportManager; import org.codehaus.xfire.xmlbeans.XmlBeansTypeRegistry; import org.company.service.server.ServiceInterface; public class ServiceInterface { private Service service; private static XFireProxyFactory proxyFactory = new XFireProxyFactory(); public ServiceInterfaceClient() { createService(); service.addEndpoint(new QName("http://www.company.org/service/server", "ServiceInterfaceLocalPort"), new QName("http://www.company.org/service/server", "ServiceInterfaceLocalBinding"), "xfire.local://ServiceInterface"); service.addEndpoint(new QName("http://www.company.org/service/server", "ServiceInterfaceHttpPort"), new QName("http://www.company.org/service/server", "ServiceInterfaceHttpBinding"), "http://localhost:8080/MyService/services/ServiceInterface"); } private void createService() { TransportManager tm = (org.codehaus.xfire.XFireFactory.newInstance().getXFire().getTransportManager()); AnnotationServiceFactory asf = new AnnotationServiceFactory( new Jsr181WebAnnotations(), tm, new AegisBindingProvider(new XmlBeansTypeRegistry())); asf.setBindingCreationEnabled(true); service = asf.create((org.company.service.server.ServiceImpl.class)); { AbstractSoapBinding soapBinding = asf.createSoap11Binding(service, new QName("http://www.company.org/service/server", "ServiceInterfaceHttpBinding"), "http://schemas.xmlsoap.org/soap/http"); } { AbstractSoapBinding soapBinding = asf.createSoap11Binding(service, new QName("http://www.company.org/service/server", "ServiceInterfaceLocalBinding"), "urn:xfire:transport:local"); } } public void addEndpoint(QName name, QName binding, String address) { service.addEndpoint((name), (binding), (address)); } public ServiceInterface getEndpoint(Endpoint endpoint) { try { return ((ServiceInterface ) proxyFactory.create((endpoint).getBinding(), (endpoint).getUrl())); } catch (MalformedURLException e) { throw new XFireRuntimeException("Invalid URL", e); } } public ServiceInterface getEndpoint(QName name) { Endpoint endpoint = service.getEndpoint((name)); if ((endpoint) == null) { throw new IllegalStateException("No such endpoint!"); } return getEndpoint((endpoint)); } public ServiceInterface getEndpoint() { if (service.getEndpoints().size() == 0) { throw new IllegalStateException("No available endpoints!"); } Endpoint endpoint = ((Endpoint) service.getEndpoints().iterator().next()); return (this).getEndpoint((endpoint)); } public ServiceInterface getServiceInterfaceLocalPort() { return (this).getEndpoint( new QName("http://www.company.org/service/server", "ServiceInterfaceLocalPort")); } public ServiceInterface getServiceInterfaceHttpPort() { return (this).getEndpoint( new QName("http://www.company.org/service/server", "ServiceInterfaceHttpPort")); } }
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |