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服务安全

作为一个服务提供商,所提供的服务若没有安全机制,则任何人都可以使用服务了。


数字签名(signature)其实是使用私钥对报文的摘要进行加密,只有报文在传输过程中不被篡改,接收端在进行数字签名验证时才可能成功。


虽然数字签名解决了完整性和不可抵赖性的安全问题,但消息体还是以明文的方式进行发送,在传输过程中,消息体的内容可能被监视。此时需要加密(encryption)。


3、CXF与Spring集成
(1)In Action

新建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中的方法取得数据了; 


(2) 客户端调用进行身份验证:

 <!-- 使用拦截器配置示例-->

 <jaxws:client id="client" serviceClass="com.dahua.icp.webservice.caze.CazeService" address="http://localhost:8080/tz/ws/caze" >
  <jaxws:outInterceptors>  
            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />  
            <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />  
            <bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">  
                <constructor-arg>  
                    <map>  
                        <entry key="action" value="UsernameToken" />
                        <entry key="passwordType" value="PasswordText" />
                        <entry key="user" value="cxfClient" />
                        <entry key="passwordCallbackRef">
                            <ref bean="clientPasswordCallback" />
                        </entry>
                    </map>  
                </constructor-arg>  
            </bean>  
        </jaxws:outInterceptors>       
 </jaxws:client>

 

(3)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值