WebService从零到项目开发使用3—技术研究之Axis2 POJO开发Web服务

来源:互联网 发布:java 可以找什么工作 编辑:程序博客网 时间:2024/05/17 11:05

1.1.      Axis2 使用POJO开发Web服务

如果考虑快速开发一个Web服务,可以创建POJO(普通现有的java对象)然后使用axis2部署到tomcat上,这种方式容易快速开发、便于整合并且易于维护。下面我们会学习到如何从Spring框架中获得一个现有的POJO,然后将其作为ARR包部署到tomcat上来发布Web服务。下面我们以pojoguidespring为示例说明。

1.1.1.             一个简单的POJO开发Web服务

1.      打开Eclipse,新建一个工程名为pojospring。

2.      将axis2.war中的axis2-web和WEB-INF文件夹复制到工程WebContent目录下。

3.      在工程下创建如下目录结构:


4.      在src下编写POJO Java类:
Weather 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;

    }

}

         WeatherServicePOJO:

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;

    }

}

5.      定义services.xml向Axis2描述该服务

<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>

服务名是WeatherService,服务作用域是application,在POJO WeatherService中有两个方法IN-ONLY和IN-OUT方法,消息接收器类型是RPC。

6.      打开Ant文件WeatherService.build.xml,进行创建POJO服务任务:

<project name="pojoguide" basedir=".." default="generate.service">

 

         <property name="service.name" value="WeatherService" />

         <property name="dest.dir" value="WebContent/WEB-INF/services" />

         <property name="dest.dir.classes" value="${dest.dir}/${service.name}" />

         <property name="axis2.home" value="WebContent/WEB-INF" />

         <path id="build.class.path">

                   <fileset dir="${axis2.home}/lib">

                            <includename="*.jar"/>

                   </fileset>

         </path>

         <!--

         <target name="clean">

                   <delete dir="${dest.dir}" />

                   <delete dir="src" includes="sample/pojo/stub/**"/>

         </target>

         -->

         <target name="prepare">

                   <mkdir dir="${dest.dir}" />

                   <mkdir dir="${dest.dir.classes}" />

                   <mkdir dir="${dest.dir.classes}/META-INF" />

         </target>

 

         <target name="generate.service" depends="prepare">

                   <copy file="src/META-INF/${service.name}/services.xml"tofile="${dest.dir.classes}/META-INF/services.xml"overwrite="true"/> 

                   <javac srcdir="src" destdir="${dest.dir.classes}"includes="sample/pojo/service/**,sample/pojo/data/**">

                            <classpathrefid="build.class.path"/>

                   </javac>                  

                   <jar basedir="${dest.dir.classes}" destfile="${dest.dir}/${service.name}.aar"/>

                   <!--

                   <copy file="${dest.dir}/${service.name}.aar" tofile="${repository.path}/services/${service.name}.aar" overwrite="true" />

                   -->

         </target>

</project>

7.      运行ant文件,在工程目录WebContent/WEB-INF/services下会生成WeatherService目录:



注意:发布服务时WeatherService.aarWeatherService仅可有一个

8.      将pojospring工程部署到Eclipse Tomcat下并启动,访问如下链接查看已发布的服务描述文件WSDL:
http://localhost:8080/pojospring/services/WeatherService?wsdl

9.      客户端使用RPCServiceClient测试发布的Web服务。编写WeatherRPCClient客户端测试类,由于该客户端没有callback,所以采用阻塞模式:(注意该客户端仅用于测试,如果与服务端分离开发的话可以使用客户端开发技术来开发,比如,动态调用接口-DII

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/pojospring/services/WeatherService");

                   options.setTo(targetEPR);

                   // Setting the weather

                   QName opSetWeather = new QName("http://service.pojo.sample", "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);

                   // Getting the weather

                   QName opGetWeather = new QName("http://service.pojo.sample", "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;

                   }

                   // 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());

         }

}

10.  运行以上代码,控制台输出:

log4j:WARN No appenders could be found for logger (org.apache.axis2.context.AbstractContext).

log4j:WARN Please initialize the log4j system properly.

Temperature : 39.3

Forecast : Cloudy with showers

Rain : true

How much rain (in inches) : 4.5

11.  下面使用Spring整合POJO。

1.1.2.             使用Spring POJO开发Web服务

1.        以上我们看到创建一个POJO服务很简单,但是这种方式有一定的限制,比如无法对Service进行初始化,这时我们需要在Service可用前手动初始化值。下面我们使用Spring避免这种缺陷。

2.        在工程lib下导入spring.jar等jar包。

3.        编写SpringInit.java,该类用于初始化Spring application Context

package sample.pojo.service;

 

import org.apache.axiom.om.OMElement;

import org.apache.axis2.context.ConfigurationContext;

import org.apache.axis2.context.OperationContext;

import org.apache.axis2.context.ServiceContext;

import org.apache.axis2.description.AxisService;

import org.apache.axis2.engine.ServiceLifeCycle;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

public class SpringInit implements ServiceLifeCycle {

         private static Log logger = LogFactory.getLog(SpringInit.class);

         // The web service

         public OMElement springInit(OMElement ignore) {

                   returnnull;

         }

         public void init(ServiceContext serviceContext) {

         }

         public void setOperationContext(OperationContext arg0) {

         }

         public void destroy(ServiceContext arg0) {

         }

         /**

          * this will be called during thedeployement time of the service.

          * irrespective of the service scope this method will be called

          */

         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() ... ");

                   }

         }

         /**

          * this will be called during thedeployement time of the service.

          * irrespective of the service scope this method will be called

          */

         public void shutDown(ConfigurationContext ignore, AxisService service) {

         }

}

 

4.        定义services.xml

<serviceGroup>

  <servicename="SpringInit"class="sample.pojo.service.SpringInit">

    <description>

      This web service initializes Spring.

    </description>

    <parametername="ServiceClass">sample.pojo.service.SpringInit</parameter>

    <parametername="ServiceTCCL">composite</parameter>

    <parametername="load-on-startup">true</parameter>

    <operationname="springInit">

      <messageReceiverclass="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>

    </operation>

  </service>

  <servicename="WeatherSpringService">

    <description>

      Weather Spring POJO Axis2 AAR deployment

    </description>

    <parametername="ServiceClass">sample.pojo.service.WeatherService</parameter>

<parametername="ServiceObjectSupplier">

org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier

</parameter>

    <parametername="SpringBeanName">weatherSpringService</parameter>

    <messageReceivers>

      <messageReceivermep="http://www.w3.org/2004/08/wsdl/in-only"

                       class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>

      <messageReceivermep="http://www.w3.org/2004/08/wsdl/in-out"

                       class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>

    </messageReceivers>

  </service>

</serviceGroup>

Server.xml文件定义了两个service描述,ServiceTCCL属性确保Spring的类加载器能应用到该Service,load-on-startup属性(必须)保证Spring application context启动创建时加载该Service,ServiceObjectSupplier通知Axis该Service由Spring容器负责创建、和初始化。

5.        在src下创建applicationContext.xml文件并添加如下配置:

<?xmlversion="1.0"encoding="UTF-8"?>

 

<!DOCTYPEbeansPUBLIC"-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">

 

<beans>

  <beanid="applicationContext"

    class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder"/>

  <beanid="weatherSpringService"class="sample.pojo.service.WeatherService">

    <propertyname="weather"ref="weatherBean"/>

  </bean>

  <beanid="weatherBean"class="sample.pojo.data.Weather">

    <propertyname="temperature"value="89.9"/>

    <propertyname="forecast"value="Sunny"/>

    <propertyname="rain"value="false"/>

    <propertyname="howMuchRain"value="0.2"/>

  </bean>

</beans>

6.        SpringInit.java的startUp方法:

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() ... ");

                   }

}

当Service发布时会先执行该方法。该方法首先获得serviceSpring的类加载器,然后使用applicationContext.xml创建applicationContext,将Spring的类加载器设置为service的加载器,刷新applicationContext,现在我们的Spring开始为service服务了。

7.        打开Ant文件SpringWeatherService.build.xml,进行创建POJO服务任务:

<project name="pojoguide" basedir=".." default="generate.service">

 

         <property name="service.name" value="SpringWeatherService" />

         <property name="dest.dir" value="WebContent/WEB-INF/services" />

         <property name="dest.dir.classes" value="${dest.dir}/${service.name}" />

         <property name="axis2.home" value="WebContent/WEB-INF" />

 

         <path id="build.class.path">

                   <fileset dir="${axis2.home}/lib">

                            <includename="*.jar"/>

                   </fileset>

         </path>   

         <target name="prepare">

                   <mkdir dir="${dest.dir}" />

                   <mkdir dir="${dest.dir.classes}" />

                   <mkdir dir="${dest.dir.classes}/META-INF" />

         </target>

         <target name="generate.service" depends="prepare">

                   <copy file="src/META-INF/${service.name}/services.xml"tofile="${dest.dir.classes}/META-INF/services.xml"overwrite="true"/>

                   <copy file="src/applicationContext.xml" tofile="${dest.dir.classes}/applicationContext.xml"overwrite="true"/>

                   <javac srcdir="src" destdir="${dest.dir.classes}"includes="sample/pojo/service/**,sample/pojo/data/**">

                            <classpathrefid="build.class.path"/>

                   </javac>               

                   <jar basedir="${dest.dir.classes}" destfile="${dest.dir}/${service.name}.aar"/>

                   <!--

                   <copy file="${dest.dir}/${service.name}.aar" tofile="${repository.path}/services/${service.name}.aar" overwrite="true" />

                   -->

         </target>

</project>

8.        编写WeatherSpringRPCClient客户端测试类:

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 WeatherSpringRPCClient {

         public static void main(String[] args1) throws AxisFault {

                   RPCServiceClient serviceClient = new RPCServiceClient();

                   Options options = serviceClient.getOptions();

                   EndpointReference targetEPR = new EndpointReference(

                                     "http://localhost:8080/pojospring/services/WeatherSpringService");

                   options.setTo(targetEPR);

                   // Get the weather (no setting, the Spring Framework has already

                   // initialized it for us)

                   QName opGetWeather = new QName("http://service.pojo.sample", "getWeather");

                   Object[] opGetWeatherArgs = new Object[] {};

                   Class[] returnTypes = new Class[] { Weather.class };

                   Object[] response = serviceClient.invokeBlocking(opGetWeather, opGetWeatherArgs, returnTypes);

                   Weather result = (Weather) response[0];

                   // display results

                   if (result == null) {

                            System.out.println("Weather didn't initialize!");

                   } else {

                            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());

                   }

         }

}

9.        运行以上代码,控制台输出:

log4j:WARN No appenders could be found for logger (org.apache.axis2.context.AbstractContext).

log4j:WARN Please initialize the log4j system properly.

Temperature  : 89.9

Forecast : Sunny

Rain : false

How much rain (in inches) : 0.2

         可见,Weather对象的初始化已经由Spring框架在启动时为我们做完了。

 资源

以上代码在工程pojospring.rar


原创粉丝点击