您的位置:首页 > 其它

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

2013-03-22 16:11 746 查看

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.aar和WeatherService仅可有一个。

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发布时会先执行该方法。该方法首先获得service和Spring的类加载器,然后使用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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: