webservice远程调用详解
webservice是跨编程语言和跨平台的远程调用技术。常见的远程调用技术还有RMI,因为webservice跨平台和跨编程语言,因此应用更广泛,但性能略低。 ? 远程调用:一台计算机a上的一个程序可以调用另一台计算机b上的一个对象的方法。 ? 关于Java webService框架,主要有AXIS、XFire、CXF,还有Java自带的JAX-WS(必须JDK6以上环境)。 ? SOAP:是在分布式的环境中交换信息的简单协议,以XML作为数据传送的方式。 SOAP=RPC+HTTP+XML SOAP RPC的工作原理:类似于web的请求/响应方式,不同之处在于web客户和web服务器之间传输的是HTML数据。在SOAP RPC模式中,SOAP客户(程序)和SOAP服务之间传输的是符合SOAP规范的XML数据。(XML中说明调用远程服务对象的哪个方法、传递的参数是什么,以及服务对象的返回结果是什么。) ? WSDL:webservice客户端要调用一个webservice服务,首先要知道这个服务的地址在哪,以及这个服务有什么方法可以调用。因此webservice服务端首先要通过一个WSDL文件来说明有什么服务可以对外调用,服务是什么,有哪些方法,方法接受的参数是什么,返回值是什么。 WSDL文件保存在服务端,可以通过url地址访问到。客户端要调用一个webservice服务之前,要知道该服务的WSDL文件的地址。webservice服务提供者可以通过两种方式暴露它的WSDL文件地址: a、注册到UDDI服务器,以便被人查找; b、直接告诉客户端调用者; ? 要访问一个远程的webservice,有两种方法: a、通过SOAP协议; b、通过REST的方式;? 1、AXIS是apache软件组织对SOAP规范的实现。 SOAP客户程序——>AXIS API—RPC请求—>AXIS web应用(SOAP服务),此web应用可以放在Tomcat容器中。 ? 在AXIS上创建和发布基于RPC的SOAP服务步骤: a、创建实现SOAP服务的java类; b、创建SOAP服务的发布描述文件; c、通过AXIS的AdminClient客户程序发布SOAP服务; ? 一个web容器中的web应用———远程访问———>另一个web容器中的AXIS应用(SOAP服务) 2、web服务开源框架XFire XFire是下一代的java soap开源框架。XFire提供了方便的API,使用这些API可以开发面向服务(SOA)的程序。 XFire是codehaus组织一个web服务开源框架项目,官方主页为http://xfire.codehaus.org. 主要特性包括: a、支持多个重要的webservice标准,包括SOAP、WSDL等。 b、支持JSR181,可以通过JDK5中的注解配置web服务。 c、支持基于HTTP、JMS等多种协议访问web服务。 d、支持spring、Pico等多种容器。 e、支持客户端和服务器代码生成。 XFire在1.2.6版本后与Celtix合并成为apache的CXF项目,主页为http://cxf.apache.org。 到XFire主页下载xfire-distribution-1.2.6.zip。解压后得到目录结构为: api目录:是XFire框架中所有类对应的Java Doc文档。 lib目录:XFire运行所依赖的jar包。 manual目录: 包含有XFire框架的帮助文档,可以从中学习更多运用XFire框架实现SOA的知识和技巧。 xFire-all-1.2.6.jar:XFire框架的jar包,包括了全部的模块。 其中lib目录中的jar包和xFire-all-1.2.6.jar是XFire运行所必须的类库。 (1)在Myeclipse中发布web服务 a、新建一个web工程,导入XFire运行所必须的jar包。如:XFireDemo b、创建服务的接口及实现类。 c、在web .xml文件中,配置XFire的servlet。 如: ? 定义在web.xml中的XFireServlet负责提供web服务,且提供WSDL。 ? d、在工程下,新建WebServices/services.xml文件。(该配置文件定义了一个web服务) 如: ? 该配置文件为XFire发布服务的配置文件,当请求服务时,XFire会根据这个配置文件解析对应的服务。 e、将此web工程发布到Tomcat中。 ? (2)在Myeclipse中调用web服务 当web服务发布后,在客户端有多种方式调用。如Myeclipse客户端、SDK方式的客户端和根据WSDL自动生成的客户端。 ? (3)XFire与spring集成(XFire运行在spring容器中) XFire提供了对spring的集成,可配置spring bean来提供web服务。 a、配置spring bean 在web.xml文件中增加spring的配置,同时将XFire的bean配置文件加入到spring容器中。 b、配置XFire Servlet 在spring容器中,需配置org.codehaus.xfire.spring.XFireSpringServlet类集中处理web服务的servlet请求。 c、配置web服务Bean 最后配置spring容器中的bean,此时XFire运行在spring容器中,故不再需要配置servicers.xml文件,而是在applicationContext.xml配置bean。 ? (4)web服务安全 作为一个服务提供商,所提供的服务若没有安全机制,则任何人都可以使用服务了。
虽然数字签名解决了完整性和不可抵赖性的安全问题,但消息体还是以明文的方式进行发送,在传输过程中,消息体的内容可能被监视。此时需要加密(encryption)。 3、CXF与Spring集成 新建web工程,如cxftest。在pom.xml中添加依赖:groupId为org.apache.cxf,artifactId分别为cxf-rt-frontend-jaxws和cxf-rt-transports-http,version为2.6.2。 a、定义接口,必须加上@webservice注解,否则会报错。如: @WebService(name="HelloService",targetNamespace="http://test.com")?? public?interface?HelloService?{ ?? ??? ?? ?@WebMethod ????@WebResult(name?=?"result") ?? ????public?String?sayHello(@WebParam(name?=?"s")String?s); ?? } ? b、实现类,其中@WebService注解表示是要发布的web服务,endpointInterface的值是该服务类对应的接口。如: @WebService(name="HelloService",targetNamespace="http://test.com",endpointInterface?=?"com.framework.webservice.HelloService") ?? public?class?HelloServiceImpl?implements?HelloService{ ?? ??? ?public?String??sayHello(String?s)?{ ?? ????????System.out.println(?"Insist?on"+s); ?? ????????return?"Insist?on"; ?? ????}??? } ? c、spring配置文件 <beans?xmlns="http://www.springframework.org/schema/beans"?? ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?? ????xmlns:jaxws="http://cxf.apache.org/jaxws"?? ????xsi:schemaLocation="http://www.springframework.org/schema/beans?? ????http://www.springframework.org/schema/beans/spring-beans.xsd??http://cxf.apache.org/jaxws?http://cxf.apache.org/schema/jaxws.xsd">?? ?? ?<import?resource="classpath:META-INF/cxf/cxf.xml"?/>?? ????<import?resource="classpath:META-INF/cxf/cxf-extension-soap.xml"?/>?? ????<import?resource="classpath:META-INF/cxf/cxf-servlet.xml"?/>?? ??? ??? <bean id="helloServiceImpl" class="com.framework.webservice.HelloServiceImpl" /> ????<jaxws:endpoint???id="hello"???implementor="#helloServiceImpl"???address="/Hello"?/>?????????? </beans>?? implementor:指明具体的实现类;address:指明这个webservice的相对地址。 ? d、web.xml文件中加入,如: <context-param>?? ????<param-name>contextConfigLocation</param-name>?? ?? ??<param-value>classpath:/applicationContext.xml</param-value>????? //加载spring配置文件 </context-param>??? <listener>?? ? ?<listener-class>?? ????????? org.springframework.web.context.ContextLoaderListener?? ? ?</listener-class>?? </listener>?? <servlet>?? ? ??<servlet-name>CXFServlet</servlet-name>?? ?? ?<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> ??? <load-on-startup>1</load-on-startup>?? </servlet>?? <servlet-mapping>? ?? ?<servlet-name>CXFServlet</servlet-name>?? ?? ?<url-pattern>/*</url-pattern>?? </servlet-mapping>?? ? e、部署到web服务器,webservice就发布成功了。可输入:http://localhost:8080/cxftest/Hello?wsdl,看其描述文件。 若此处为<url-pattern>/ws/*</url-pattern>,则应输入:??http://localhost:8080/cxftest/ws/Hello?wsdl ? f、创建客户端调用webservice测试 //创建WebService客户端代理工厂 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); //注册WebService接口 factory.setServiceClass(HelloService.class); //设置WebService地址 factory.setAddress(http://localhost:8080/cxftest/Hello); HelloService hello = (HelloService)factory.create(); //调用webservice接口方法 hello.sayHello("hello");//返回Insist?on ? 3、PS (1)在另一个web应用中调用webservice有两种方法: 一、 a、定义接口 @WebService(name="HelloService",targetNamespace="http://test.com")?? public?interface?HelloService?{ ?? ??? ?? ?@WebMethod ????@WebResult(name?=?"result") ?? ????public?String?sayHello(@WebParam(name?=?"s")String?s); ?? } b、在applicationContext.xml文件中加入: ???? <import?resource="classpath:META-INF/cxf/cxf.xml"?/>?? ????<import?resource="classpath:META-INF/cxf/cxf-extension-soap.xml"?/>?? ????<import?resource="classpath:META-INF/cxf/cxf-servlet.xml"?/>?? ? <jaxws:client id="helloClient" serviceClass="com.framework.webservice.client.HelloService" address="http://localhost:8080/cxftest/Hello" /> c、在action中引用: @Resource(name="helloClient") private HelloService ?helloService; 之后,就可以在此action中调用此HelloService中的方法取得数据了;? ? 二、 a、定义接口 @WebService(name="HelloService",targetNamespace="http://test.com")?? public?interface?HelloService?{ ?? ??? ?? ?@WebMethod ????@WebResult(name?=?"result") ?? ????public?String?sayHello(@WebParam(name?=?"s")String?s); ?? } b、在applicationContext.xml文件中加入: ?? ?<import?resource="classpath:META-INF/cxf/cxf.xml"?/>?? ????<import?resource="classpath:META-INF/cxf/cxf-extension-soap.xml"?/>?? ????<import?resource="classpath:META-INF/cxf/cxf-servlet.xml"?/>?? ? ??? <bean id="helloService" class="com.framework.webservice.HelloService" factory-bean="helloClientFactory"?factory-method="create"/> ??? <bean id="helloClientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> ??????????? <property?name="serviceClass" value="com.framework.webservice.HelloService"?/> ??????????? <property name="address" value="http://localhost:8080/cxftest/Hello" /> ??? </bean> c、在action中引用: @Resource(name="helloService") private HelloService helloService;? ?之后,就可以在此action中调用此HelloService中的方法取得数据了;?
?<!-- 使用拦截器配置示例--> ?<jaxws:client id="client" serviceClass="com.dahua.icp.webservice.caze.CazeService" address="http://localhost:8080/tz/ws/caze" > ? (3) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |