XFireHome M5M6-SNAPSHOTDevelopersDeveloper Space |
A great feature of XFire is the integration with the Plexus container. Exposing Components as ServicesTo have XFire expose your component as a service is fairly easy. If XFire sees that the <serviceClass/> defined in your configuration is an XFire component, it will use that component by doing a lookup() instead of trying to instantiate that object directly via the constructor. Configuring Services via PlexusInstead of a services.xml file, you can use Plexus configurations to configure your components. The following example will show a small "Hello World" application that exposes a service using XFire and Plexus and is built using Maven2, so you should install M2 before you start, because it will take the load of dependency handling from you. OverviewFor the Hello World project you need following directory layout: helloworld/ |-- helloworld-application | |-- pom.xml | `-- src | |-- main | | |-- java | | | `-- org | | | `-- codehaus | | | `-- xfire | | | `-- helloworld | | | |-- DefaultHelloWorldService.java | | | `-- HelloWorldService.java | | `-- resources | | `-- META-INF | | `-- plexus | | `-- components.xml | `-- test | `-- java |-- helloworld-web | |-- pom.xml | `-- src | `-- main | `-- webapp | `-- WEB-INF | |-- plexus.properties | |-- plexus.xml | `-- web.xml `-- pom.xml As you see, the project is split up into two subprojects, helloworld-application which includes the service implementation and configuration and helloworld-web, which is only the web-application. Let's start with the different project descriptors. Project descriptorsThe root project is made up of two modules. helloworld/pom.xml <project> <modelVersion>4.0.0</modelVersion> <groupId>org.codehaus.xfire</groupId> <version>1.0</version> <artifactId>helloworld</artifactId> <packaging>pom</packaging> <modules> <module>helloworld-application</module> <module>helloworld-web</module> </modules> </project> The web-app's project object model looks like this: helloworld/helloworld-application/pom.xml <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.codehaus.xfire</groupId> <version>1.0</version> <artifactId>helloworld</artifactId> </parent> <artifactId>helloworld-application</artifactId> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.codehaus.xfire</groupId> <artifactId>xfire-plexus</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>plexus</groupId> <artifactId>plexus-container-default</artifactId> <version>1.0-alpha-5-SNAPSHOT</version> </dependency> <dependency> <groupId>plexus</groupId> <artifactId>plexus-servlet</artifactId> <version>1.0-beta-3-SNAPSHOT</version> </dependency> </dependencies> </project> This subproject extends the parent project and depends on the xfire-plexus module. Normally you wouldn't need to specify the other dependencies, as Maven2 can handle transitive dependencies, but using newer versions of plexus-container-default and plexus-servlet generally leads to better results for me. The web-application module depends on the application module and extends the parent project: helloworld/helloworld-web/pom.xml <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.codehaus.xfire</groupId> <version>1.0</version> <artifactId>helloworld</artifactId> </parent> <artifactId>helloworld-web</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.codehaus.xfire</groupId> <artifactId>helloworld-application</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <finalName>helloworld</finalName> </build> </project> Here we don't need to specify any dependencies, as Maven2 already knows them from the helloworld-application module. The Web Services and their configurationThe first step is to define an interface for the Hello World service. This interface offers only one method for now: helloworld/helloworld-application/src/main/java/org/codehaus/xfire/helloworld/HelloWorldService.java package org.codehaus.xfire.helloworld; public interface HelloWorldService { String ROLE = HelloWorldService.class.getName(); String helloWorld(); } The role string in the interface is used later by plexus in order to access the component. An implementation of HelloWorldService is neccessary for execution of the webservice. helloworld/helloworld-application/src/main/java/org/codehaus/xfire/helloworld/DefaultHelloWorldService.java package org.codehaus.xfire.helloworld; public class DefaultHelloWorldService implements HelloWorldService { public String helloWorld() { return "Hello World"; } } In the configuration section we define the mapping of service interface and service implementation as well helloworld/helloworld-application/src/main/resources/META-INF/plexus/components.xml <?xml version="1.0" encoding="UTF-8"?> <component-set> <components> <component> <role>org.codehaus.xfire.helloworld.HelloWorldService</role> <implementation>org.codehaus.xfire.helloworld.DefaultHelloWorldService</implementation> </component> <component> <role>org.codehaus.xfire.plexus.config.ConfigurationService</role> <implementation>org.codehaus.xfire.plexus.config.DefaultConfigurationService</implementation> <configuration> <services> <service> <name>HelloWorld</name> <namespace>http://xfire.codehaus.org/helloworld</namespace> <serviceClass>org.codehaus.xfire.helloworld.HelloWorldService</serviceClass> </service> </services> </configuration> <requirements> <requirement> <role>org.codehaus.xfire.plexus.config.Configurator</role> <role-hint>annotation</role-hint> </requirement> </requirements> </component> </components> </component-set> The second component definition is used for defining which components to expose as web services. In the configuration element you specify a service element for every service to expose. A service needs a name, a namespace-URI and a serviceClass. If this class is the role of a component defined elsewhere, plexus will chose the right implementation once the service is requested. The web applicationThis module need a web.xml file first which loads the PlexusServlet and defines the XFire-Servlet. You can later on access your service at http://localhost:8080/helloworld/services/Hello helloworld/helloworld-web/src/main/webapp/WEB-INF/web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>Hello World Service</display-name> <listener> <listener-class>org.codehaus.plexus.servlet.PlexusServletContextListener</listener-class> </listener> <servlet> <servlet-name>XFire</servlet-name> <display-name>XFire Servlet</display-name> <servlet-class> org.codehaus.xfire.plexus.PlexusXFireServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>XFire</servlet-name> <url-pattern>/servlet/XFireServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>XFire</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app> Finally, the plexus.xml defines which components should be loaded at web-application startup. This is neccessary for loading the components.xml and the enclosed service definitions. helloworld/helloworld-web/src/main/webapp/WEB-INF/plexus.xml <?xml version="1.0" encoding="UTF-8"?> <plexus> <load-on-start> <component> <role>org.codehaus.xfire.plexus.config.ConfigurationService</role> </component> </load-on-start> </plexus> Building and RunningYou can build the whole application by running m2 install in the root directory. After deploying helloworld/helloworld-web/target/helloworld.war to your servlet container, you can access the web service at http://localhost:8080/helloworld/services/Hello or get an WSDL service description at http://localhost:8080/helloworld/services/Hello?wsdl. |