Return-Path:
Want a quick way to get a Web service up and running in no time? Well
-then, you should consider creating a Plain Old Java Object (POJO) to deploy
-using Apache Axis2 on Apache Tomcat. POJOs are fast to build and easy to
-maintain, meaning you'll save a lot of time building and debugging your code.
-This document shows you how to take a simple POJO, and deploy it on Apache
-Tomcat as a Web service in the exploded directory format. You'll also be
-shown how to take a POJO based on the Spring Framework, and deploy that as an
-AAR packaged Web service on Tomcat. The task of building a Web service can sometimes be overwhelming, but not
-with POJOs! The old-school Plain Old Java Object is a simple and quick way to
-get most, if not all, of your currently existing Java classes up on the Web
-as readily accessible Web services. This document will show you how to build
-a POJO-style Web service with Apache Axis2 and Tomcat, organized as
-follows: The code for the document can be found at Axis2_HOME/samples/pojoguide
-& Axis2_HOME/samples/pojoguidespring once you extract the Axis2 Stadard
-Distribution, and it might help to go grab it now to help you as you
-follow along. Let's get started. The POJO you'll be using throughout this document is a Weather service
-POJO that consists of two classes: WeatherService and Weather. Weather
-contains the Weather data: Temperature, forecast, rain (will it rain?), and
-howMuchRain (See Code Listing 1). Code Listing 1: The Weather POJO And here's the WeatherService class, shown in Code Listing 2. Code Listing 2: The WeatherService class Note that it's all just straight POJOs with field items and
- Got the POJOs? Great. This section will show you how to package them in
-the exploded directory format for easy deployment. First you'll look at the
-services.xml file that defines the Web service, and then you'll build the
-files using Apache Ant, and deploy the
-Web service on Tomcat. Before Axis2 can understand what is going on, you have to tell it to use
-the services.xml file. Let's get right into it (see Code Listing 3). Code Listing 3: The service definition file: services.xml The name of the service is specified as WeatherService and the scope of
-the service is application. As you can see in the WeatherService POJO, there
-are two methods, an IN-ONLY method and a IN-OUT method, hence the ordering
-for the messageReceiver elements within the messageReceivers tag. Lastly, the
-ServiceClass parameter specifies the class of the Web service, which is
-sample.pojo.service.WeatherService. When operations of your Web service get
-called, the methods of the WeatherService class will be called. Next you'll
-take a look at an easy method of building your application using Ant. Ant is a slick build tool. It helps
-reduce time to build applications, and several of the Axis2 command-line
-tools create build.xml files for you, so that's why we'll use it here. We
-won't go into the build.xml file that you'll be using in too much detail, so
-here are the main Ant tasks you'll be using: Before you can build the source, however, you'll need to download the
-Axis2 1.1.1-bin and 1.1.1-war distributions here. Then modify the following
-line inside the build.xml file (in the Axis2_HOME/samples/pojoguide directory
-in the extracted Axis2 1.1.1 Standard Binary (bin) Distribution) : This modification contains the path to the root of the unzipped Axis2
-1.1.1-bin download. With
-that explanation, you'll now build the source by typing the following: ant The following directory format should now exist at
-build/WeatherService: Simple isn't it? An excellent way to dive into Web services
-development. Now get a Tomcat distribution (I
-used v5.5), and start it up by running bin/startup.bat or
-bin/startup.sh. Once it's running, deploy the Axis2 1.1.1-war by
-copying the axis2.war file to Tomcat's webapps directory. Tomcat will proceed
-by deploying axis2 and un-archive it into the webapps directory. Now copy the
-WeatherService directory created when building our project to:
-<tomcat-home>/webapps/axis2/WEB-INF/services. The service should quickly deploy, and you'll test the Web service using
-the RPCServiceClient in the next section. OK, so the Web service should be running on Tomcat. Now you'll build a
-simple RPCServiceClient and test the POJO Web service. You'll first start out
-with the class constructs, creating the RPCServiceClient and initializing the
-values of the Weather class within the Web service (See Code Listing 4). Code Listing 4: Setting the weather The most interesting code to note is in bold font. Notice the targetEPR
-variable you create, setting the endpoint reference to
-http://localhost:8080/axis2/services/WeatherService. This is where you
-deployed it on Axis2. You can also verify this by asking Axis2 to list its
-services by going to the following URL:
-http://localhost:8080/axis2/services/listServices. Next the opSetWeather variable gets setup, pointing to the setWeather
-operation. Then the Weather data gets created and initialized. Lastly, you
-invoke the Web service, which initializes the weather data (you'll verify
-this soon). Next you get back the weather data (see Code Listing 5). Code Listing 5: Getting the weather data First you set the operation in opGetWeather to getWeather. Then you create
-an empty argument list. Note this time you expect something back from the Web
-service, and so you create a list of return types. Then you invoke the Web
-service using a blocking call and wait for the weather data to be returned to
-you, and you place it in the result variable. Lastly, you make sure it isn't
-null and that it was successfully initialized by the previous call to
-setWeather. Now display the data to verify that it is indeed what you set it
-to (see Code Listing 6). Code Listing 6: Displaying the data You should receive the data shown in Code Listing 7. Code Listing 7: Output from running the client Excellent, you have a working POJO Web service! Next you'll quickly morph
-this one into a Spring based POJO. We've covered the strengths of using POJO based Web services, but what
-about any limitations? One main limitation of POJO based Web services is the
-lack of initialization support (meaning that you have to go into your Web
-service and initialize the values before the Web service is completely
-useful), but you'll soon see how to overcome that limitation with a Spring
-based POJO, covered next. Spring is a hot framework for J2EE and makes bean usage a breeze. You'll
-use it in this section to create a Spring based POJO Web service. For this
-section you'll need the spring.jar from the latest 1.x Spring download. If you take a look at the source code of this document in
-Axis2_HOME/samples/pojoguidespring (to see how the Spring based POJO Web
-service is coded), you can see that the Weather class didn't change at all
-and the WeatherService class only got its name changed to
-WeatherSpringService. You'll also notice an applicationContext.xml file, which we'll cover
-later: it's used to setup the beans used in our Web service. Now you might wonder what the SpringInit.java class is for: This service
-is necessary, however, to initialize the Spring Framework's application
-context. The client is pretty much the same, except you won't use it to initialize
-the Weather data in the Web service, since Spring does that for you using
-Inversion of Control (IoC), which is covered next. Because the core POJOs didn't change, you'll move straight to the
-services.xml file. It's a bit longer this time because it instantiates two
-services in one file (see Code Listing 7). Code Listing 7: Defining the services: services.xml You'll see a few familiar items in the above listing, and several changes.
-Once again, the items in bold are most important. The ServiceTCCL property
-under the SpringInit service makes sure that the Spring class loader is used
-for the Web service, allowing it to properly instantiate the Spring
-application context. The load-on-startup variable is a must-have so that the
-service loads up immediately on startup, creating the Spring application
-context. The WeatherSpringService stays mostly the same to the WeatherService
-previously with a couple additions: The ServiceObjectSupplier provides the
-service with the Spring application context, making it "Spring Aware." Lastly, the SpringBeanName points to the name of the bean associated with
-this Web service, which is defined in the applicationContext.xml file
-(essentially the WeatherSpringService). We'll cover the
-applicationContext.xml file next. The application context:
-applicationContext.xml file tells the Spring Framework, what beans are
-defined. For this example, you'll define three of them (see Code Listing
-8). Code Listing 8: Defining the application context:
-applicationContext.xml The first one is Axis2's hook into Spring's application context (needed
-since AAR deployment is quite different from regular WAR deployment). Next,
-you define the bean pointed to by the services.xml file, the
-weatherSpringService bean that points to the WeatherSpringService class. It
-has one field property that gets initialized by the Spring Framework,
-weather, which will be set to the weatherBean. The weatherBean is an
-instantiation of the Weather class that holds information on the weather.
-Spring will initialize it to the values shown above, and set the Weather
-object in the WeatherSpringService class to this weatherBean instantiation.
-Thus, when you deploy the Web service you won't have to instantiate the
-values because they'll already be set. Next up is the SpringInit class. Without the Spring application context being initialized quickly, you'll
-run into problems. The SpringInit class initializes the Spring application
-context on startup because it is a ServiceLifeCycle class, whose startUp
-method gets called upon loading the class (and because its load-on-startup
-property is set in the serices.xml file). The only code worth mentioning in
-this class is shown in Code Listing 9. Code Listing 9: SpringInit's startUp method Note that this method retrieves the Spring class loader, creates an
-application context with applicationContext.xml as the parameters. This new
-application context then gets the Spring class loader as its class loader.
-The Spring Framework is now up and ready for our WeatherSpringService. Great, your POJO is now ready for primetime within the Spring Framework.
-Before you build, you'll first need to make sure the axis2-spring-1.1.1.jar and
-spring.jar files are in the project's Axis2_HOME/lib directory. Note: The service will not deploy if you add the above jars files to the service archive due to cloass loding issues. Now build the source and create an AAR file by typing:
-ant It'll be created at target/WeatherSpringService.aar. Copy it over
-to <tomcat-home>/webapps/axis2/WEB-INF/services, and Axis2
-should deploy it quickly. Next test the Web service to see if Spring really will initialize the
-weather data for you. It's as simple as it was for the other Web service, except this time type:
-ant rpc.client Feel free to browse the code for this client in
-src/client/WeatherSpringRPCClient.java. Essentially, this client does the
-exact same thing as the client testing the WeatherService, except this one
-skips the "Setting the weather" task since the weather data should already
-have been set by the Spring framework at startup. Thus, you should get the following as output from the client: Which is exactly the values you set them to be in the
-applicationContext.xml file! Apache Axis2 is an excellent way to expose your POJOs as Web services, and
-Spring adds greater flexibility to your POJOs by adding beans support and
-initialization abilities, along with all the other goodies provided by the
-Spring framework. Apache Axis2-http://ws.apache.org/axis2/ Axis2 Architecture-http://ws.apache.org/axis2/1_0/Axis2ArchitectureGuide.html Introduction to Apache Axis2-http://www.redhat.com/magazine/021jul06/features/apache_axis2/ Working With Apache Axis2-http://www.wso2.net/articles/axis2/java/2006/09/13/working-with-axis2 Apache Tomcat-http://tomcat.apache.org Spring Framework-http://www.springframework.org/ Want a quick way to get a Web service up and running in no time? Well
+then, you should consider creating a Plain Old Java Object (POJO) to deploy
+using Apache Axis2 on Apache Tomcat. POJOs are fast to build and easy to
+maintain, meaning you'll save a lot of time building and debugging your code.
+This document shows you how to take a simple POJO, and deploy it on Apache
+Tomcat as a Web service in the exploded directory format. You'll also be
+shown how to take a POJO based on the Spring Framework, and deploy that as an
+AAR packaged Web service on Tomcat. The task of building a Web service can sometimes be overwhelming, but not
+with POJOs! The old-school Plain Old Java Object is a simple and quick way to
+get most, if not all, of your currently existing Java classes up on the Web
+as readily accessible Web services. This document will show you how to build
+a POJO-style Web service with Apache Axis2 and Tomcat, organized as
+follows: The code for the document can be found at Axis2_HOME/samples/pojoguide
+& Axis2_HOME/samples/pojoguidespring once you extract the Axis2 Stadard
+Distribution, and it might help to go grab it now to help you as you
+follow along. Let's get started. The POJO you'll be using throughout this document is a Weather service
+POJO that consists of two classes: WeatherService and Weather. Weather
+contains the Weather data: Temperature, forecast, rain (will it rain?), and
+howMuchRain (See Code Listing 1). Code Listing 1: The Weather POJO And here's the WeatherService class, shown in Code Listing 2. Code Listing 2: The WeatherService class Note that it's all just straight POJOs with field items and
+ Got the POJOs? Great. This section will show you how to package them in
+the exploded directory format for easy deployment. First you'll look at the
+services.xml file that defines the Web service, and then you'll build the
+files using Apache Ant, and deploy the
+Web service on Tomcat. Before Axis2 can understand what is going on, you have to tell it to use
+the services.xml file. Let's get right into it (see Code Listing 3). Code Listing 3: The service definition file: services.xml The name of the service is specified as WeatherService and the scope of
+the service is application. As you can see in the WeatherService POJO, there
+are two methods, an IN-ONLY method and a IN-OUT method, hence the ordering
+for the messageReceiver elements within the messageReceivers tag. Lastly, the
+ServiceClass parameter specifies the class of the Web service, which is
+sample.pojo.service.WeatherService. When operations of your Web service get
+called, the methods of the WeatherService class will be called. Next you'll
+take a look at an easy method of building your application using Ant. Ant is a slick build tool. It helps
+reduce time to build applications, and several of the Axis2 command-line
+tools create build.xml files for you, so that's why we'll use it here. We
+won't go into the build.xml file that you'll be using in too much detail, so
+here are the main Ant tasks you'll be using: Before you can build the source, however, you'll need to download the
+Axis2 1.1.1-bin and 1.1.1-war distributions here. Then modify the following
+line inside the build.xml file (in the Axis2_HOME/samples/pojoguide directory
+in the extracted Axis2 1.1.1 Standard Binary (bin) Distribution) : This modification contains the path to the root of the unzipped Axis2
+1.1.1-bin download. With
+that explanation, you'll now build the source by typing the following: ant The following directory format should now exist at
+build/WeatherService: Simple isn't it? An excellent way to dive into Web services
+development. Now get a Tomcat distribution (I
+used v5.5), and start it up by running bin/startup.bat or
+bin/startup.sh. Once it's running, deploy the Axis2 1.1.1-war by
+copying the axis2.war file to Tomcat's webapps directory. Tomcat will proceed
+by deploying axis2 and un-archive it into the webapps directory. Now copy the
+WeatherService directory created when building our project to:
+<tomcat-home>/webapps/axis2/WEB-INF/services. The service should quickly deploy, and you'll test the Web service using
+the RPCServiceClient in the next section. OK, so the Web service should be running on Tomcat. Now you'll build a
+simple RPCServiceClient and test the POJO Web service. You'll first start out
+with the class constructs, creating the RPCServiceClient and initializing the
+values of the Weather class within the Web service (See Code Listing 4). Code Listing 4: Setting the weatherPOJO Web Services using Apache Axis2
-
-Content
-
-
-
-
-Introduction
-
-
-
-
-The POJO
-
-package sample.pojo.data;
-
-public class Weather{
- float temperature;
- String forecast;
- boolean rain;
- float howMuchRain;
-
- public void setTemperature(float temp){
- temperature = temp;
- }
-
- public float getTemperature(){
- return temperature;
- }
-
- public void setForecast(String fore){
- forecast = fore;
- }
-
- public String getForecast(){
- return forecast;
- }
-
- public void setRain(boolean r){
- rain = r;
- }
-
- public boolean getRain(){
- return rain;
- }
-
- public void setHowMuchRain(float howMuch){
- howMuchRain = howMuch;
- }
-
- public float getHowMuchRain(){
- return howMuchRain;
- }
-}
-
-package sample.pojo.service;
-
-import sample.pojo.data.Weather;
-
-public class WeatherService{
- Weather weather;
-
- public void setWeather(Weather weather){
- this.weather = weather;
- }
-
- public Weather getWeather(){
- return this.weather;
- }
-}
-
-getter
and setter
methods for each field. Next,
-you'll take a look at what you need to do to make it ready for deployment on
-Apache Axis2 and Tomcat.POJO Web Service Using Apache Axis2 and Tomcat
-
-Defining the Service: services.xml
-
-<service name="WeatherService" scope="application">
- <description>
- Weather POJO Service
- </description>
- <messageReceivers>
- <messageReceiver
- mep="http://www.w3.org/2004/08/wsdl/in-only"
- class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
- <messageReceiver
- mep="http://www.w3.org/2004/08/wsdl/in-out"
- class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
- </messageReceivers>
- <parameter name="ServiceClass">
- sample.pojo.service.WeatherService
- </parameter>
-</service>
-
-Building the POJO Web Service Using Apache Ant
-
-
-
-
-<property name="axis2.home" value="c:\apps\axis2" />
-
- - WeatherService
- - META-INF
- - services.xml
- - sample
- - pojo
- - data
- - Weather.class
- - service
- - WeatherService.class
-
-Testing the POJO Web Service Using RPCServiceClient
-
-package sample.pojo.rpcclient;
-
-import javax.xml.namespace.QName;
-
-import org.apache.axis2.AxisFault;
-import org.apache.axis2.addressing.EndpointReference;
-import org.apache.axis2.client.Options;
-import org.apache.axis2.rpc.client.RPCServiceClient;
-
-import sample.pojo.data.Weather;
-
-
-public class WeatherRPCClient {
-
- public static void main(String[] args1) throws AxisFault {
-
- RPCServiceClient serviceClient = new RPCServiceClient();
-
- Options options = serviceClient.getOptions();
-
- EndpointReference targetEPR = new EndpointReference(
- "http://localhost:8080/axis2/services/WeatherService");
- options.setTo(targetEPR);
-
- // Setting the weather
- QName opSetWeather =
- new QName("http://service.pojo.sample/xsd", "setWeather");
-
- Weather w = new Weather();
-
- w.setTemperature((float)39.3);
- w.setForecast("Cloudy with showers");
- w.setRain(true);
- w.setHowMuchRain((float)4.5);
-
- Object[] opSetWeatherArgs = new Object[] { w };
-
- serviceClient.invokeRobust(opSetWeather, opSetWeatherArgs);
-...
-
-...
- serviceClient.invokeRobust(opSetWeather, opSetWeatherArgs);
-
- // Getting the weather
- QName opGetWeather =
- new QName("http://service.pojo.sample/xsd", "getWeather");
-
- Object[] opGetWeatherArgs = new Object[] { };
- Class[] returnTypes = new Class[] { Weather.class };
-
- Object[] response = serviceClient.invokeBlocking(opGetWeather,
- opGetWeatherArgs, returnTypes);
-
- Weather result = (Weather) response[0];
-
- if (result == null) {
- System.out.println("Weather didn't initialize!");
- return;
- }
-...
-
-...
- return;
- }
-
- // Displaying the result
- System.out.println("Temperature : " +
- result.getTemperature());
- System.out.println("Forecast : " +
- result.getForecast());
- System.out.println("Rain : " +
- result.getRain());
- System.out.println("How much rain (in inches) : " +
- result.getHowMuchRain());
-
- }
-}
-
-rpc.client.run:
- [java] Temperature : 39.3
- [java] Forecast : Cloudy with showers
- [java] Rain : true
- [java] How much rain (in inches) : 4.5
-
-Limitations and Strengths of POJO
-
-Spring-based POJO Web Service
-
-Quick Introduction
-
-The Service Definition: services.xml
-
-<serviceGroup>
- <service name="SpringInit"
-class="sample.spring.service.SpringInit">
- <description>
- This web service initializes Spring.
- </description>
- <parameter name="ServiceClass">
- sample.spring.service.SpringInit
- </parameter>
- <parameter name="ServiceTCCL">composite</parameter>
- <parameter name="load-on-startup">true</parameter>
- <operation name="springInit">
- <messageReceiver
- class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
- </operation>
- </service>
- <service name="WeatherSpringService">
- <description>
- Weather Spring POJO Axis2 AAR deployment
- </description>
- <parameter name="ServiceClass">
- sample.spring.service.WeatherSpringService
- </parameter>
- <parameter name="ServiceObjectSupplier">
-org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier
- </parameter>
- <parameter name="SpringBeanName">
- weatherSpringService
- </parameter>
- <messageReceivers>
- <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
- class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
- <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
- class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
- </messageReceivers>
- </service>
-</serviceGroup>
-
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
-"http://www.springframework.org/dtd/spring-beans.dtd">
-
-<beans>
- <bean id="applicationContext" class=
-"org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
-
- <bean id="weatherSpringService"
- class="sample.spring.service.WeatherSpringService">
- <property name="weather" ref="weatherBean"/>
- </bean>
-
- <bean id="weatherBean" class="sample.spring.bean.Weather">
- <property name="temperature" value="89.9"/>
- <property name="forecast" value="Sunny"/>
- <property name="rain" value="false"/>
- <property name="howMuchRain" value="0.2"/>
- </bean>
-</beans>
-
-Initializing the Spring application context: SpringInit
-
- public void startUp(ConfigurationContext ignore,
- AxisService service) {
- ClassLoader classLoader = service.getClassLoader();
- ClassPathXmlApplicationContext appCtx = new
- ClassPathXmlApplicationContext(new String[]
- {"applicationContext.xml"},
- false);
- appCtx.setClassLoader(classLoader);
- appCtx.refresh();
- if (logger.isDebugEnabled()) {
- logger.debug("\n\nstartUp() set spring classloader " +
- "via axisService.getClassLoader() ... ");
- }
- }
-
-Build and Deploy Using Apache Axis2 and Tomcat
-
-Testing Using an RPCServiceClient
-
-run.client:
- [javac] Compiling 1 source file to C:\axis2-1.1.1\samples\pojoguidespring\build\cl
-asses
- [java] Temperature : 89.9
- [java] Forecast : Sunny
- [java] Rain : false
- [java] How much rain (in inches) : 0.2
-
-Summary
-
-For Further Study
-
-POJO Web Services using Apache Axis2
+
+Content
+
+
+
+
+Introduction
+
+
+
+
+The POJO
+
+package sample.pojo.data;
+
+public class Weather{
+ float temperature;
+ String forecast;
+ boolean rain;
+ float howMuchRain;
+
+ public void setTemperature(float temp){
+ temperature = temp;
+ }
+
+ public float getTemperature(){
+ return temperature;
+ }
+
+ public void setForecast(String fore){
+ forecast = fore;
+ }
+
+ public String getForecast(){
+ return forecast;
+ }
+
+ public void setRain(boolean r){
+ rain = r;
+ }
+
+ public boolean getRain(){
+ return rain;
+ }
+
+ public void setHowMuchRain(float howMuch){
+ howMuchRain = howMuch;
+ }
+
+ public float getHowMuchRain(){
+ return howMuchRain;
+ }
+}
+
+package sample.pojo.service;
+
+import sample.pojo.data.Weather;
+
+public class WeatherService{
+ Weather weather;
+
+ public void setWeather(Weather weather){
+ this.weather = weather;
+ }
+
+ public Weather getWeather(){
+ return this.weather;
+ }
+}
+
+getter
and setter
methods for each field. Next,
+you'll take a look at what you need to do to make it ready for deployment on
+Apache Axis2 and Tomcat.POJO Web Service Using Apache Axis2 and Tomcat
+
+Defining the Service: services.xml
+
+<service name="WeatherService" scope="application">
+ <description>
+ Weather POJO Service
+ </description>
+ <messageReceivers>
+ <messageReceiver
+ mep="http://www.w3.org/2004/08/wsdl/in-only"
+ class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
+ <messageReceiver
+ mep="http://www.w3.org/2004/08/wsdl/in-out"
+ class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
+ </messageReceivers>
+ <parameter name="ServiceClass">
+ sample.pojo.service.WeatherService
+ </parameter>
+</service>
+
+Building the POJO Web Service Using Apache Ant
+
+
+
+
+<property name="axis2.home" value="c:\apps\axis2" />
+
+ - WeatherService
+ - META-INF
+ - services.xml
+ - sample
+ - pojo
+ - data
+ - Weather.class
+ - service
+ - WeatherService.class
+
+Testing the POJO Web Service Using RPCServiceClient
+
+package sample.pojo.rpcclient;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.client.Options;
+import org.apache.axis2.rpc.client.RPCServiceClient;
+
+import sample.pojo.data.Weather;
+
+
+public class WeatherRPCClient {
+
+ public static void main(String[] args1) throws AxisFault {
+
+ RPCServiceClient serviceClient = new RPCServiceClient();
+
+ Options options = serviceClient.getOptions();
+
+ EndpointReference targetEPR = new EndpointReference(
+ "http://localhost:8080/axis2/services/WeatherService");
+ options.setTo(targetEPR);
+
+ // Setting the weather
+ QName opSetWeather =
+ new QName("http://service.pojo.sample/xsd", "setWeather");
+
+ Weather w = new Weather();
+
+ w.setTemperature((float)39.3);
+ w.setForecast("Cloudy with showers");
+ w.setRain(true);
+ w.setHowMuchRain((float)4.5);
+
+ Object[] opSetWeatherArgs = new Object[] { w };
+
+ serviceClient.invokeRobust(opSetWeather, opSetWeatherArgs);
+...
The most interesting code to note is in bold font. Notice the targetEPR +variable you create, setting the endpoint reference to +http://localhost:8080/axis2/services/WeatherService. This is where you +deployed it on Axis2. You can also verify this by asking Axis2 to list its +services by going to the following URL: +http://localhost:8080/axis2/services/listServices.
+ +Next the opSetWeather variable gets setup, pointing to the setWeather +operation. Then the Weather data gets created and initialized. Lastly, you +invoke the Web service, which initializes the weather data (you'll verify +this soon). Next you get back the weather data (see Code Listing 5).
+ +Code Listing 5: Getting the weather data
+... + serviceClient.invokeRobust(opSetWeather, opSetWeatherArgs); + + // Getting the weather + QName opGetWeather = + new QName("http://service.pojo.sample/xsd", "getWeather"); + + Object[] opGetWeatherArgs = new Object[] { }; + Class[] returnTypes = new Class[] { Weather.class }; + + Object[] response = serviceClient.invokeBlocking(opGetWeather, + opGetWeatherArgs, returnTypes); + + Weather result = (Weather) response[0]; + + if (result == null) { + System.out.println("Weather didn't initialize!"); + return; + } +...+ +
First you set the operation in opGetWeather to getWeather. Then you create +an empty argument list. Note this time you expect something back from the Web +service, and so you create a list of return types. Then you invoke the Web +service using a blocking call and wait for the weather data to be returned to +you, and you place it in the result variable. Lastly, you make sure it isn't +null and that it was successfully initialized by the previous call to +setWeather. Now display the data to verify that it is indeed what you set it +to (see Code Listing 6).
+ +Code Listing 6: Displaying the data
+... + return; + } + + // Displaying the result + System.out.println("Temperature : " + + result.getTemperature()); + System.out.println("Forecast : " + + result.getForecast()); + System.out.println("Rain : " + + result.getRain()); + System.out.println("How much rain (in inches) : " + + result.getHowMuchRain()); + + } +}+ +
You should receive the data shown in Code Listing 7.
+ +Code Listing 7: Output from running the client
+rpc.client.run: + [java] Temperature : 39.3 + [java] Forecast : Cloudy with showers + [java] Rain : true + [java] How much rain (in inches) : 4.5+ +
Excellent, you have a working POJO Web service! Next you'll quickly morph +this one into a Spring based POJO.
+ + +We've covered the strengths of using POJO based Web services, but what +about any limitations? One main limitation of POJO based Web services is the +lack of initialization support (meaning that you have to go into your Web +service and initialize the values before the Web service is completely +useful), but you'll soon see how to overcome that limitation with a Spring +based POJO, covered next.
+ + +Spring is a hot framework for J2EE and makes bean usage a breeze. You'll +use it in this section to create a Spring based POJO Web service. For this +section you'll need the spring.jar from the latest 1.x Spring download.
+ + + +If you take a look at the source code of this document in +Axis2_HOME/samples/pojoguidespring (to see how the Spring based POJO Web +service is coded), you can see that the Weather class didn't change at all +and the WeatherService class only got its name changed to +WeatherSpringService.
+ +You'll also notice an applicationContext.xml file, which we'll cover +later: it's used to setup the beans used in our Web service.
+ +Now you might wonder what the SpringInit.java class is for: This service +is necessary, however, to initialize the Spring Framework's application +context.
+ +The client is pretty much the same, except you won't use it to initialize +the Weather data in the Web service, since Spring does that for you using +Inversion of Control (IoC), which is covered next.
+ + +Because the core POJOs didn't change, you'll move straight to the +services.xml file. It's a bit longer this time because it instantiates two +services in one file (see Code Listing 7).
+ +Code Listing 7: Defining the services: services.xml
+<serviceGroup> + <service name="SpringInit" +class="sample.spring.service.SpringInit"> + <description> + This web service initializes Spring. + </description> + <parameter name="ServiceClass"> + sample.spring.service.SpringInit + </parameter> + <parameter name="ServiceTCCL">composite</parameter> + <parameter name="load-on-startup">true</parameter> + <operation name="springInit"> + <messageReceiver + class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> + </operation> + </service> + <service name="WeatherSpringService"> + <description> + Weather Spring POJO Axis2 AAR deployment + </description> + <parameter name="ServiceClass"> + sample.spring.service.WeatherSpringService + </parameter> + <parameter name="ServiceObjectSupplier"> +org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier + </parameter> + <parameter name="SpringBeanName"> + weatherSpringService + </parameter> + <messageReceivers> + <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" + class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/> + <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" + class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> + </messageReceivers> + </service> +</serviceGroup>+ +
You'll see a few familiar items in the above listing, and several changes. +Once again, the items in bold are most important. The ServiceTCCL property +under the SpringInit service makes sure that the Spring class loader is used +for the Web service, allowing it to properly instantiate the Spring +application context. The load-on-startup variable is a must-have so that the +service loads up immediately on startup, creating the Spring application +context. The WeatherSpringService stays mostly the same to the WeatherService +previously with a couple additions: The ServiceObjectSupplier provides the +service with the Spring application context, making it "Spring Aware."
+ +Lastly, the SpringBeanName points to the name of the bean associated with +this Web service, which is defined in the applicationContext.xml file +(essentially the WeatherSpringService). We'll cover the +applicationContext.xml file next. The application context: +applicationContext.xml file tells the Spring Framework, what beans are +defined. For this example, you'll define three of them (see Code Listing +8).
+ +Code Listing 8: Defining the application context: +applicationContext.xml
+<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" +"http://www.springframework.org/dtd/spring-beans.dtd"> + +<beans> + <bean id="applicationContext" class= +"org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" /> + + <bean id="weatherSpringService" + class="sample.spring.service.WeatherSpringService"> + <property name="weather" ref="weatherBean"/> + </bean> + + <bean id="weatherBean" class="sample.spring.bean.Weather"> + <property name="temperature" value="89.9"/> + <property name="forecast" value="Sunny"/> + <property name="rain" value="false"/> + <property name="howMuchRain" value="0.2"/> + </bean> +</beans>+ +
The first one is Axis2's hook into Spring's application context (needed +since AAR deployment is quite different from regular WAR deployment). Next, +you define the bean pointed to by the services.xml file, the +weatherSpringService bean that points to the WeatherSpringService class. It +has one field property that gets initialized by the Spring Framework, +weather, which will be set to the weatherBean. The weatherBean is an +instantiation of the Weather class that holds information on the weather. +Spring will initialize it to the values shown above, and set the Weather +object in the WeatherSpringService class to this weatherBean instantiation. +Thus, when you deploy the Web service you won't have to instantiate the +values because they'll already be set.
+ +Next up is the SpringInit class.
+ + +Without the Spring application context being initialized quickly, you'll +run into problems. The SpringInit class initializes the Spring application +context on startup because it is a ServiceLifeCycle class, whose startUp +method gets called upon loading the class (and because its load-on-startup +property is set in the serices.xml file). The only code worth mentioning in +this class is shown in Code Listing 9.
+ +Code Listing 9: SpringInit's startUp method
+public void startUp(ConfigurationContext ignore, + AxisService service) { + ClassLoader classLoader = service.getClassLoader(); + ClassPathXmlApplicationContext appCtx = new + ClassPathXmlApplicationContext(new String[] + {"applicationContext.xml"}, + false); + appCtx.setClassLoader(classLoader); + appCtx.refresh(); + if (logger.isDebugEnabled()) { + logger.debug("\n\nstartUp() set spring classloader " + + "via axisService.getClassLoader() ... "); + } + }+ +
Note that this method retrieves the Spring class loader, creates an +application context with applicationContext.xml as the parameters. This new +application context then gets the Spring class loader as its class loader. +The Spring Framework is now up and ready for our WeatherSpringService.
+ +Great, your POJO is now ready for primetime within the Spring Framework. +Before you build, you'll first need to make sure the axis2-spring-1.1.1.jar and +spring.jar files are in the project's Axis2_HOME/lib directory.
+ +Note: The service will not deploy if you add the above jars files to the service archive due to cloass loding issues.
+Now build the source and create an AAR file by typing: +ant
+ +It'll be created at target/WeatherSpringService.aar. Copy it over +to <tomcat-home>/webapps/axis2/WEB-INF/services, and Axis2 +should deploy it quickly.
+ +Next test the Web service to see if Spring really will initialize the +weather data for you.
+ + +It's as simple as it was for the other Web service, except this time type: +ant rpc.client
+ +Feel free to browse the code for this client in +src/client/WeatherSpringRPCClient.java. Essentially, this client does the +exact same thing as the client testing the WeatherService, except this one +skips the "Setting the weather" task since the weather data should already +have been set by the Spring framework at startup.
+ +Thus, you should get the following as output from the client:
+run.client: + [javac] Compiling 1 source file to C:\axis2-1.1.1\samples\pojoguidespring\build\cl +asses + [java] Temperature : 89.9 + [java] Forecast : Sunny + [java] Rain : false + [java] How much rain (in inches) : 0.2+ +
Which is exactly the values you set them to be in the +applicationContext.xml file!
+ + +Apache Axis2 is an excellent way to expose your POJOs as Web services, and +Spring adds greater flexibility to your POJOs by adding beans support and +initialization abilities, along with all the other goodies provided by the +Spring framework.
+ + +Apache Axis2-http://ws.apache.org/axis2/
+ +Axis2 Architecture-http://ws.apache.org/axis2/1_0/Axis2ArchitectureGuide.html
+ +Introduction to Apache Axis2-http://www.redhat.com/magazine/021jul06/features/apache_axis2/
+ +Working With Apache Axis2-http://www.wso2.net/articles/axis2/java/2006/09/13/working-with-axis2
+ +Apache Tomcat-http://tomcat.apache.org
+ +Spring Framework-http://www.springframework.org/
+ + --------------------------------------------------------------------- To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org For additional commands, e-mail: axis-cvs-help@ws.apache.org