`
zym_nanako
  • 浏览: 85651 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java Web Service之客户端实现

阅读更多
Java Web Service的客户端实现有三种
1. 生成的stub
2. 动态代理
3. 动态调用接口
其中生 成stub是最常用的。stub是用JAX-RPC编译器根据WSDL文档生成的,其主要功能是将对endpoint接口的方法调用转化为SOAP 消息,并且负责将返回的SOAP响应转换为方法的返回值,把SOAP fault转化为方法的异常。JAX-RPC编译器产生的stub除了要实现endpoint接口外,还需要实现或继承 javax.xml.rpc.Stub接口或其实现的子类(Axis中是org.apache.axis.client.Stub)。 javax.xml.rpc.Stub接口主要定义了和网络通讯和认证相关的属性的设置和获取的机制。
Java Web Service的客户端实现有三种
1. 生成的stub
2. 动态代理
3. 动态调用接口
其 中生成stub是最常用的。stub是用JAX-RPC编译器根据WSDL文档生成的,其主要功能是将对endpoint接口的方法调用转化为SOAP 消息,并且负责将返回的SOAP响应转换为方法的返回值,把SOAP fault转化为方法的异常。JAX-RPC编译器产生的stub除了要实现endpoint接口外,还需要实现或继承 javax.xml.rpc.Stub接口或其实现的子类(Axis中是org.apache.axis.client.Stub)。 javax.xml.rpc.Stub接口主要定义了和网络通讯和认证相关的属性的设置和获取的机制。其代码如下:
package javax.xml.rpc;
import java.util.Iterator;

public interface Stub {

    // Standard property: The Web service's Internet address.
    public static String ENDPOINT_ADDRESS_PROPERTY;
    // Standard property: Password for authentication.
    public static String PASSWORD_PROPERTY;
    // Standard property: User name for authentication.
    public static String USERNAME_PROPERTY;
    // Standard property: Boolean flag for maintaining an HTTP session.
    public static String SESSION_MAINTAIN_PROPERTY;

    // Given a property name, get its value.
    public Object _getProperty(java.lang.String name);
    // Get the names of all the properties the stub supports.
    public Iterator _getPropertyNames();
    // Configure a property on the stub.
    public void _setProperty(java.lang.String name, java.lang.Object value);
}

JAX -RPC编译器产生还可以产生一个和WSDL中service元素对应的Service接口,该接口组合了多个port,也就是多个Stub。该接口继承 了javax.xml.rpc.Service。在J2EE环境中Service接口通常通过JNDI lookup得到。
在J2EE中使用生成的stub的典型用例如下:
代码:
package com.jwsbook.jaxrpc;
import javax.servlet.http.*;
import javax.servlet.*;
import javax.naming.InitialContext;

public class BookQuoteServlet_1 extends javax.servlet.http.HttpServlet {
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  throws ServletException,java.io.IOException {
    try{
      String isbn = req.getParameter("isbn");

      InitialContext jndiContext = new InitialContext();

      BookQuoteService service = (BookQuoteService)
      jndiContext.lookup("java:comp/env/service/BookQuoteService");

      BookQuote bookQuote = service.getBookQuotePort();

      float price = bookQuote.getBookPrice( isbn );

      java.io.Writer outStream = resp.getWriter();
      outStream.write("<html><body>The wholesale price for ISBN:"+isbn+
                    " = "+price+"</body></html>");
    }catch(javax.naming.NamingException ne){
      throw new ServletException(ne);
    }catch(javax.xml.rpc.ServiceException se){
      throw new ServletException(se);
    }
  }
部署说明文件:
<service-ref xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote" >
    <service-ref-name>service/BookQuoteService</service-ref-name>
    <service-interface>com.jwsbook.jaxrpc.BookQuoteService</service-interface>
    <wsdl-file>BookQuote.wsdl</wsdl-file>
    <service-qname>mh:BookQuoteService</service-qname>
</service-ref>

一 般都是通过JNDI查询到相应的Service接口,然后从Service接口中得到stub,最后调用web service的方法。部署文件中申明了名为"service/BookQuoteService"的Service接口,在代码里获取该接口的代码是 jndiContext.lookup("java:comp/env/service/BookQuoteService"),前缀"java: comp/env/"是所有J2EE资源在JNDI树种的parent Context。

在非J2EE环境中实现web service客户端
在 非J2EE环境中也可以实现web service客户端,这时需要用到javax.xml.rpc.ServiceFactory(或其子类,在axis中是 org.apache.axis.client.ServiceFactory)的静态方法loadService得到service接口。接下来的调用 代码和J2EE中的类似。

动态代理调用
动态代理调用是Java web service的另一种方式。对于使用该方式的客户端代码,和生成stub的方式相比较,其变化不是很大。它和生成stub的方式主要区别在于前者在编译时刻产生service接口和stub,后者则将这部分工作延迟到运行时刻。
动态代理调用的典型代码和部署说明文件:
package com.jwsbook.jaxrpc;
import javax.naming.InitialContext;

public class JaxRpcExample_2 {
  public static void main(String [] args) throws Exception{
    String isbn = args[0];

    InitialContext jndiContext = new InitialContext();

    javax.xml.rpc.Service service = (javax.xml.rpc.Service)
    jndiContext.lookup("java:comp/env/service/Service");

    BookQuote BookQuote_proxy = (BookQuote)
                                service.getPort(BookQuote.class);

    float price = BookQuote_proxy.getBookPrice( isbn );

    System.out.println("The price is = "+price);
  }
}

<service-ref xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote" >
    <service-ref-name>service/Service</service-ref-name>
    <service-interface>javax.xml.rpc.Service</service-interface>
    <wsdl-file>BookQuote.wsdl</wsdl-file>
    <service-qname>mh:BookQuoteService</service-qname>
</service-ref>


由 于不需要在编译时刻产生service接口和stub,用JNDI lookup和部署说明时只使用了javax.xml.rpc.Service。得到service接口后通过getPort方法可以取得动态代理的 stub。getPort有两种版本,getPort(java.lang.Class endpointInterface)和getPort(javax.xml.namespace.QName portName,java.lang.Class endpointInterface),通常当WSDL中一个PortType有一种以上的绑定时,如果需要得到某个绑定的port接口就使用后者,否者 使用前者。QName是该绑定的完全限定名称,有命名空间加上局部名构成。对应的QName对象的构造方法有构造函数法和静态valueOf法,实例如 下:
// Use constructor method
QName portName =
          new QName("http://www.Monson-Haefel/jwsbook/BookQuote",
          "BookQuoteLiteralPort");
          
// Use static valueOf() method
String s = "{http://www.Monson-Haefel/jwsbook/BookQuote}BookQuoteLiteralPort";
QName qname2 = QName.valueOf(s);

valueOf方法接受的String参数以"{namespace}localName"的模式构成。
PortType有一种以上的绑定时还需要在JAX-RPC Mapping 文件中说明不指定QName版本的getPort方法对应的port绑定。示例:
<?xml version='1.0' encoding='UTF-8' ?>
<java-wsdl-mapping
  xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote"...>
  ...
  <service-endpoint-interface-mapping>
    <service-endpoint-interface>com.jwsbook.jaxrpc.BookQuote
    </service-endpoint-interface>
    <wsdl-port-type>mh:BookQuote</wsdl-port-type>
    <wsdl-binding>mh:BookQuote_LiteralBinding</wsdl-binding>
    ...
  </service-endpoint-interface-mapping>
</java-wsdl-mapping>


使用QName的动态代理调用实例:
package com.jwsbook.jaxrpc;
import javax.naming.InitialContext;
import javax.xml.namespace.QName;

public class JaxRpcExample_3 {
  public static void main(String [] args) throws Exception{
    String isbn = args[0];

    InitialContext jndiContext = new InitialContext();

    javax.xml.rpc.Service service = (javax.xml.rpc.Service)
    jndiContext.lookup("java:comp/env/service/Service");

    QName portName =
          new QName("http://www.Monson-Haefel/jwsbook/BookQuote",
          "BookQuoteLiteralPort");

    BookQuote BookQuote_proxy = (BookQuote)
                               service.getPort(portName, BookQuote.class);

    float price = BookQuote_proxy.getBookPrice( isbn );

    System.out.println("The price is = "+price);
  }
}

动态代理的底层实现是用java的反射机制和java.lang.reflect.Proxy完成的。

动态调用接口(DII)

动态调用接口的通常使用顺序:
1. 获得一个通用的service接口,比如通过JNDI lookup
2. 构造代表WSDL中port和operation的QName对象,作为service接口的createCall方法的参数,得到Call对象。
3. 准备operation所需的参数,如果是原子类型则需要将其包装成相应的对象类型。视operation是否有返回值调用invoke或invokeOneWay方法。
4. 如果operation定义了INOUT,OUT参数,则在invoke后调用getOutputValues,比如:java.util.List outputParams = call.getOutputValues();
完整的代码示例:
package com.jwsbook.jaxrpc;
import javax.naming.InitialContext;
import javax.xml.rpc.Service;
import javax.xml.rpc.Call;
import javax.xml.namespace.QName;

public class JaxRpcExample_4 {
  public static void main(String [] args) throws Exception{
    String isbn = args[0];

    InitialContext jndiContext = new InitialContext();

    javax.xml.rpc.Service service = (javax.xml.rpc.Service)
    jndiContext.lookup("java:comp/env/service/Service");

    QName portName =
     new QName("http://www.Monson-Haefel.com/jwsbook/BookQuote",
               "BookQuotePort");
    QName operationName =
     new QName("http://www.Monson-Haefel.com/jwsbook/BookQuote",
               "getBookPrice");

    Call call = service.createCall(portName,operationName);

    Object [] inputParams = new Object[]{isbn};

    Float price = (Float)call.invoke(inputParams);

    System.out.println("The price is = "+price.floatValue());
 }
}
分享到:
评论

相关推荐

    Java Web Service的客户端实现

    【Java Web Service客户端实现详解】 Java Web Service是一种基于标准的、平台无关的、用于构建分布式应用程序的技术,它允许服务提供者和服务消费者通过网络进行通信。客户端实现Java Web Service主要包括三种方式...

    XFire Java Web Service 客户端

    本文将深入探讨XFire Java Web Service客户端的使用和相关知识点。 一、XFire简介 XFire是Apache CXF项目的一个前身,它是一款高效的、开源的Java Web Service实现。XFire的目标是提供一个轻量级、快速且易于使用...

    ASP.net 中用C#调用Java web service 图解教程

    ASP.NET 中使用 C# 调用 Java Web Service ...在 ASP.NET 中使用 C# 调用 Java Web Service 需要了解 Web Service 的基本概念、使用 C# 调用 Java Web Service 和在 ASP.NET 中实现 Web Service 的客户端和服务器端。

    Web Service通用客户端和测试工具

    wsCaller是使用Java语言编写的Web Service通用客户端和测试工具。wsCaller可执行程序的发布方式为一个wsCaller.jar包,不包含Java运行环境。你可以把wsCaller.jar复制到任何安装了Java运行环境(要求安装JRE/JDK ...

    web service 客户端java例子

    二、Java Web Service客户端开发工具 1. JAX-WS(Java API for XML Web Services):这是Java官方提供的用于创建和使用SOAP Web服务的标准库。它包含一系列API,如JAXB(Java Architecture for XML Binding)用于XML...

    WSDL生成Web Service java客户端

    本教程将围绕“WSDL生成Web Service java客户端”这一主题,详细介绍如何利用WSDL文件创建Java客户端来调用Web服务。 首先,WSDL文件是一种XML格式的文档,它描述了一个Web服务的接口,包括服务提供的操作、消息...

    java+xfire(web service) + php 客户端 并实现文件加密

    标题 "java+xfire(web service) + php 客户端 并实现文件加密" 描述了一个集成项目,其中涉及到Java、XFire(一个基于Java的Web服务实现框架)和PHP的交互,以及文件加密功能。这个项目的目标是构建一个安全的分布式...

    基于Delphi的Web Service 客户端调用

    一旦某个 Web Service 被实现,其他应用程序或 Web Service 可以直接发现和调用该服务。 ##### 1.2 Web Service 的基本元素和操作 - **服务(Service)**:遵循一定规则被使用的应用程序。 - **服务提供者...

    基于Axis的Web Service客户端调用

    【标题】基于Axis的Web Service客户端调用 在IT领域,Web Service是一种通过网络进行通信的标准协议,它允许不同系统间的应用程序互相交换数据。而Apache Axis是Java平台上的一个开源工具,专门用于创建和部署Web ...

    使用Eclipse的Axis1.4插件开发Web Service及客户端

    - 创建一个新的Java项目,例如`AxisClientDemo`,用于生成Web Service客户端代码。 - 使用Eclipse的`新建 Web Service Client`向导,输入服务的WSDL地址(即`...

    Java完整的Web Service示例代码,学会做web service程序

    在Java中,创建Web Service客户端通常涉及以下步骤: 1. **生成客户端代理类**:基于服务端的WSDL(Web Service Description Language)文件,你可以使用XFire的工具(如xsi或wsimport)来生成客户端所需的代理类。...

    Web+Service通用客户端和测试工具Java源码

    【标题】"Web+Service通用客户端和测试工具Java源码" 涉及的主要知识点是Web服务客户端的开发以及测试工具的实现,其中核心语言是Java。在Web服务领域,客户端通常用于与服务器进行交互,获取或发送数据,而测试工具...

    java web service 教程

    ### Java Web Service 教程详解 #### 一、引言 在现代软件开发领域中,Web服务技术扮演着至关重要的角色。它不仅为不同应用程序之间的交互提供了标准的方式,还极大地促进了分布式系统的构建和发展。本教程旨在...

    java调用java web service

    - Eclipse、IntelliJ IDEA等IDE提供了集成的Web Service客户端工具,简化了调用过程。只需配置WSDL URL,IDE会自动生成必要的客户端代码。 - Apache CXF、Metro等开源框架提供了更高级的功能,如端到端的调试、WS-...

    JAVA实现web service

    Java 实现Web Service是一种在分布式环境中交换数据和服务的常见方式,尤其在企业级应用中广泛使用。Web Service基于开放标准,允许不同系统间的互操作性,无论它们是用何种编程语言或操作系统构建的。在本篇文章中...

    Web Service Java C# 实现 订餐小系统

    在这个项目中,Java用于创建Web Service服务器端,而C#则用于开发客户端应用,实现订餐功能。 **1. Web Service** Web Service的核心是SOAP(Simple Object Access Protocol),它是一种基于XML的协议,用于在...

    Java web Service性能监视

    为了实现Java Web Service的性能监视,系统需要满足一些功能性要求。首先,必须能够监控Web服务,识别哪些对象是服务接口。其次,需要能够访问节点上的Web服务信息。此外,通信相关的性能数据是关键,如SOAP消息的...

Global site tag (gtag.js) - Google Analytics