Spring 企业级开发应用---------AXIS和spring的远程服务整合的应用

Spring框架对远程访问技术提供了很好的集成机制,Spring目前支持的技术包括:

1.RemoteMethodInvocation(RMI)。通过RmiProxyFactoryBean和RmiServiceExporter,Spring支持以java.rmi.Remote和java.rmi.RemoteException定义的传统RMI接口,提供经由RMI的透明访问;

2.Spring内置的HTTPinvoker远程调用机制。Spring开发团队意识到在RMI服务和基于HTTP的服务(如Hessian和Burlap)之间的空白。一方面,RMI使用Java标准的对象序列化,但很难穿越防火墙;另一方面,Hessian/Burlap能很好地穿过防火墙工作,但使用自己私有的一套对象序列化机制。因此,Spring的HTTPinvoker应运而生。HTTPinvoker是一个全新的远程调用模型,作为Spring框架的一部分,来执行基于HTTP的远程调用(可穿越防火墙),并使用Java的序列化机制(从而降低开发工作的难度)。当参数或返回值是复杂类型,并且不能通过Hessian的序列化机制序列化时,Httpinvoker就很有优势。Spring中相应的支持类是HttpInvokerProxyFactoryBean和HttpInvokerServiceExporter;

3.Hessian。作为一个轻量级分布式组件技术,Hessian采用了自己定义的二进制协议,这似乎与目前业界大量应用SOAP的趋势背道而驰,但对于一些简单的远程访问服务,Hessian足够应对。在Spring中,通过HessianProxyFactoryBean和HessianServiceExporter两个类,我们可以透明地将需要对外提供的服务发布出去,当然这里依旧采用Caucho这家来自California的公司的二进制协议;

4.Burlap。Burlap可以说是Hessian的XML版本。Spring中的支持类包括BurlapProxyFactoryBean和BurlapServiceExporter;

5.JAXRPC(JavaAPIsforXML-basedRemoteProcedureCall)。Spring支持通过JAXRPC访问的WebService。事实上,Spring对于WebService的封装相当简单,Spring提供了一个代理工厂Bean:JaxRpcPortProxyFactoryBean,能让你在应用中无缝集成一个websevice,作为另一个Bean的协作者,JaxRpcPortProxyFactoryBean类用JAX-RPC来访问远程WebService。

6.JMS。Spring中对应的支持类包括JmsInvokerServiceExporter和JmsInvokerProxyFactoryBean。

    这里,我们着重讨论一下Spring对于Web Service的支持。这种支持包括两方面:

第一,基于JAX-RPC发布WebService。

    第二,访问Web Service。

    对于需要发布为Web Service的业务逻辑bean,只需要继承Spring的ServletEndpointSupport 类即可。假设有如下业务接口以及相应的实现类:

publicinterfaceSayHello

{

publicStringsayHello(Stringwho);

}

publicclassSayHelloImplimplementsSayHello

{

publicStringsayHello(Stringwho)

{

return"Hello,"+who;

}

}

如果需要将SayHelloImpl 发布为Web Service,则需要编写一个Web Service类,让该类实现SayHello接口,并继承ServletEndpointSupport类。示例如下:

public class SayHelloEndPoint extends ServletEndpointSupport implements SayHello

{

  private SayHello sh;

  protected void onInit()

{

this.sh=(SayHello)getWebApplicationContext().getBean("sayHello");

  }

  //将业务逻辑bean的业务方法公开发布为WebService

publicStringsayHello(Stringwho)throwsRemoteException

{

returnsh.sayHello(who);

}

}

    而后,定义Spring的配置文件,在配置文件中部署业务bean,示例如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN"

  "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<beanid="sayHello"class="com.ws.SayHelloImpl">

<propertyname=>

</bean>

</beans>

    然后修改web.xml文件,让AxisServlet拦截某些请求 ,示例如下:

<?xmlversion="1.0"encoding="ISO-8859-1"?>

<!DOCTYPEweb-appPUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>

    <!-- 定义AxisServlet-->

<servlet>

<servlet-name>AxisServlet</servlet-name>

<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>

  </servlet>

      <!-- 映射AxisServlet-->

<servlet-mapping>

<servlet-name>AxisServlet</servlet-name>

<url-pattern>/axis/*</url-pattern>

</servlet-mapping>

</web-app>

    在上述配置文件中,可以看到所有匹配/axis/*模式的请求都由AxisServlet处理。即:Spring发布的Web Service都在放在axis路径下。    然后编写WSDL文件,或者使用工具生成。WSDL文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<!--wsdl的根元素,包含schema等信息-->

<deploymentxmlns="http://xml.apache.org/axis/wsdd/"

xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

<!--wsdl的全局配置-->

<globalConfiguration>

<parametername="adminPassword"value="admin"/>

<parametername="sendXsiTypes"value="true"/>

<parametername="sendMultiRefs"value="true"/>

<parametername="sendXMLDeclaration"value="true"/>

<parametername="axis.sendMinimizedElements"value="true"/>

<requestFlow>

<handlertype="java:org.apache.axis.handlers.JWSHandler">

<parametername="scope"value="session"/>

</handler>

<handlertype="java:org.apache.axis.handlers.JWSHandler">

<parametername="scope"value="request"/>

<parametername="extension"value=".jwr"/>

</handler>

</requestFlow>

</globalConfiguration>

<handlername="Authenticate"type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>

<handlername="LocalResponder"type="java:org.apache.axis.transport.local.LocalResponder"/>

<handlername="URLMapper"type="java:org.apache.axis.handlers.http.URLMapper"/>

<!--定义WebService的管理台-->

<servicename="AdminService"provider="java:MSG">

<parametername="allowedMethods"value="AdminService"/>

<parametername="enableRemoteAdmin"value="false"/>

<parametername="className"value="org.apache.axis.utils.Admin"/>

<namespace>http://xml.apache.org/axis/wsdd/</namespace>

</service>

<!--定义自己的WebService-->

<servicename="SayHelloService"provider="java:RPC">

<parametername="allowedMethods"value="*"/>

<!--定义WebService的实现类-->

<parametername="className"value="com.ws.SayHelloEndpoint"/>

</service>

<!--定义WebSerivice的系统服务。-->

<servicename="Version"provider="java:RPC">

<parametername="allowedMethods"value="getVersion"/>

<parametername="className"value="org.apache.axis.Version"/>

</service>

<transportname="http">

<requestFlow>

<handlertype="URLMapper"/>

<handlertype="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>

</requestFlow>

</transport>

<transportname="local">

<responseFlow>

<handlertype="LocalResponder"/>

</responseFlow>

</transport>

</deployment>

经过上述这些步骤,可将部署在Spring的普通业务逻辑bean发布成Web Service。

Spring发布的WebService是标准的基于SOAP协议的WebService。因此可以使用标准客户端访问,也可以利用IoC容器来管理WebService,利用IoC容器时,必须借助于JaxRpcPortProxyFactoryBean。

使用标准客户端访问Web Service非常简单,只需要获得WebService的URL以及方法名即可。根据上面的发布,知道Web Service的URL如下:http://localhost:8080/axis-spring/axis/SayHelloService,则客户端代码示例如下:

public class WebServiceClient

{

publicstaticvoidmain(Stringargs[])

{

System.out.println("开始调用WebService");

try

{

//WebService所在的URL

Stringendpoint="http://localhost:8080/axis-spring/axis/SayHelloService";

//创建Service对象,Service对用用于创建Call对象

Serviceservice=newService();

//创建Call对象,Call对象用于调用服务

Callcall=(Call)service.createCall();

//为Call对象设置WebService的url

call.setTargetEndpointAddress(newjava.net.URL(endpoint));

//为Call对象设置调用的方法名

call.setOperationName("sayHello");

//调用WebService的方法,并获得返回值

          String s = (String)call.invoke(new Object[] {"刘德华"});

          System.out.println(s);

}

catch(Exceptione)

{

System.out.println(e.toString());

}

System.out.println("调用WebService正常结束");

}

}

而如果利用IoC容器管理WebService,必须借助于JaxRpcPortProxyFactoryBean类,该类是个工厂bean,与所有的工厂bean一样,对该bean的请求将返回它的产品。

配置JaxRpcPortProxyFactoryBean,只需提供WebService的URL、命名空间等必需信息,将可以返回WebService服务。在Spring配置文件中JaxRpcPortProxyFactoryBean的定义如下:

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

<!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN"

"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<!--配置测试bean-->

<beanid="test"class="com.ws.Test">

<propertyname="sayHello">

<reflocal="sayHelloService"/>

</property>

</bean>

<!--配置WebServicebean-->

<beanid="sayHelloService"class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">

<!--配置WebService实现的接口-->

<propertyname="serviceInterface">

<value>com.ws.SayHello</value>

</property>

<!--配置WebService的wsdl的URL-->

<propertyname="wsdlDocumentUrl">

<value>http://localhost:8080/axis-spring/axis/SayHelloService?wsdl</value>

</property>

<!--配置WebService的命名空间uri-->

<propertyname="namespaceUri">

<value>http://localhost:8080/axis-spring/axis/SayHelloService</value>

</property>

<!--配置WebService的服务名-->

<propertyname="serviceName">

<value>SayHelloService</value>

</property>

<!--配置WebService的portName-->

<propertyname="portName">

<value>SayHelloService"</value>

</property>

</bean>

</beans>

相关推荐