加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

从WSDL文档中生成客户端支持代码

发布时间:2020-12-16 23:20:48 所属栏目:安全 来源:网络整理
导读:enerating Client-Support Code from a WSDL 通过Java提供的"wsimport"工具可以很容易完成基于SOAP协议的Web服务客户端生成工作。这个工具可以从对应的WSDL文档的服务描述中生成客户端支持代码或其他相关资源。输入并执行如下命令: %?wsimport? 执行后,将

enerating Client-Support Code from a WSDL

通过Java提供的"wsimport"工具可以很容易完成基于SOAP协议的Web服务客户端生成工作。这个工具可以从对应的WSDL文档的服务描述中生成客户端支持代码或其他相关资源。输入并执行如下命令:

 
 
  1. %?wsimport?

执行后,将会打印出该命令程序的使用帮助。下面我们将通过此命令工具为TimeServer服务产生客户端开发的相关支持代码。

启动ch01.ts.TimeServerPublisher程序后,执行如下命令:

  • %?wsimport?-keep?-p?client?http://localhost:9876/ts?wsdl?
  • 执行后将会在"client"子目录下面产生两个源代码文件和两个与之对应的已经编译好的Class文件。命令行最后面的URL地址,和前面最初由Perl、Ruby和Java语言编写的客户端请求Web服务对应的WSDL文档时所给出的服务契约地址一样。"-p"选项用来指定生成的Java包名称,此处使用"client"作为包名称。包名称可以是符合Java包命名规则的任何名称,wsimport工具通过指定的包名称创建包对应子目录。"-keep"选项用来指示是否保留编译后的源文件,这个例子中,我们保留源文件留作验证。"-p"选项是比较重要的,这是由于wsimport命令产生的TimeServer.class文件名称同先前编译的服务端点接口(SEI,Service Endpoint Interface)拥有同样的名字。如果没有指定包名称,wsimport默认使用服务实现的包名称作为客户端代码包名称,此处将会默认使用"ch01.ts"作为包名称。简单来说,使用"-p"选项可以防止编译好的SEI文件不被wsimport工具产生的文件覆盖。如果已经将WSDL文档保存在本地(比如,文件被命名为ts.wsdl),那么,wsimport可以写成:

  • %?wsimport?-keep?-p?client?ts.wsdl?
  • 示例2-2和示例2-3是由wsimport所生成的两个Java源文件,不过这里删除了wsimport工具生成的注释内容。

    示例2-2:由wsimport生成的TimeServer服务接口

  • package?client; ?
  • ?
  • import?javax.jws.WebMethod; ?
  • import?javax.jws.WebResult; ?
  • import?javax.jws.WebService; ?
  • import?javax.jws.soap.SOAPBinding; ?
  • ?
  • @WebService(name?=?"TimeServer",?targetNamespace?=?"http://ts.ch01/") ?
  • @SOAPBinding(style?=?SOAPBinding.Style.RPC) ?
  • public?interface?TimeServer?{ ?
  • ????@WebMethod?
  • ????@WebResult(partName?=?"return") ?
  • ????public?String?getTimeAsString(); ?
  • ?
  • ????long?getTimeAsElapsed(); ?
  • }?
  • 示例2-3:由wsimport生成的TimeServerImplService实现类

    import?java.net.MalformedURLException; ?
    
      
      
  • import?java.net.URL; ?
  • import?javax.xml.namespace.QName; ?
  • import?javax.xml.ws.Service; ?
  • import?javax.xml.ws.WebEndpoint; ?
  • import?javax.xml.ws.WebServiceClient; ?
  • ?
  • @WebServiceClient(name?=?"TimeServerImplService",?
  • ??????????????????targetNamespace?=?"http://ts.ch01/",?
  • ??????????????????wsdlLocation?=?"http://localhost:9876/ts?wsdl") ?
  • class?TimeServerImplService?extends?Service?{ ?
  • ????private?final?static?URL?TIMESERVERIMPLSERVICE_WSDL_LOCATION; ?
  • ????static?{ ?
  • ????????URL?url?=?null; ?
  • ????????try?{ ?
  • ????????????url?=?new?URL("http://localhost:9876/ts?wsdl"); ?
  • ????????} ?
  • ????????catch?(MalformedURLException?e)?{ ?
  • ????????????e.printStackTrace(); ?
  • ????????} ?
  • ????????TIMESERVERIMPLSERVICE_WSDL_LOCATION?=?url; ?
  • ????} ?
  • public?TimeServerImplService(URL?wsdlLocation,?QName?serviceName)?{ ?
  • ????????super(wsdlLocation,?serviceName); ?
  • } ?
  • ? ?
  • 示例2-3:由wsimport生成的TimeServerImplService实现类(续例) ?
  • ????public?TimeServerImplService()?{ ?
  • ????????super(TIMESERVERIMPLSERVICE_WSDL_LOCATION,?
  • ??new?QName("http://ts.ch01/",?"TimeServerImplService")); ?
  • ????} ?
  • ?
  • ????@WebEndpoint(name?=?"TimeServerImplPort") ?
  • ????public?TimeServer?getTimeServerImplPort()?{ ?
  • return?(TimeServer)super.getPort( ??????"TimeServerImplPort"),?
  • ??????????????????????????????????TimeServer.class); ?
  • ????} ?
  • }?
  • 由wsimport产生的源文件有3点需要注意。第一,客户端接口client.TimeServer定义了同目标SEI接口TimeServer相同的方法。这些方法包括服务请求操作getTimeAsString和getTimeAsElapsed两个方法。第二,实现类client.TimeServerImplService包括一个无参构造函数,同目标Java客户端TimeClient中构造服务对象时非常地类似。第三,TimeServerImplService类封装了getTimeServerImplPort方法,该方法返回一个client.TimeServer对象实例,该对象实例支持对两个预先定义的Web服务操作的调用。综合接口client.TimeServer和实现类client.TimeServerImplService的定义可以看出,编写一个基于Java语言的服务调用客户端是非常简单的。示例2-4展示了利用wsimport工具产生的客户端支持代码来调用Web服务。

    示例2-4:使用wsimport生成的代码编写的Java服务调用客户端

    class?TimeClientWSDL?{ ?
    
      
      
  • ????static?void?main(String[?]?args)?{ ?
  • ???????//?The?TimeServerImplService?class?is?the?Java?type?bound?to ?
  • ???????//?the?service?section?of?the?WSDL?document. ?
  • ???????TimeServerImplService?service?=?new?TimeServerImplService(); ?
  • ?
  • ???????//?The?TimeServer?interface?is?the?Java?type?bound?to ?
  • ???????//?the?portType?section?of?the?WSDL?document. ?
  • ???????TimeServer?eif?=?service.getTimeServerImplPort(); ?
  • ?
  • ???????//?Invoke?the?methods. ?
  • ???????System.out.println(eif.getTimeAsString()); ?
  • ???????System.out.println(eif.getTimeAsElapsed()); ?
  • ????} ?
  • }?
  • 示例2-4中的服务调用客户端和前面的TimeClient客户端在功能上是一样的,但是这个客户端编写起来却非常容易。尤为重要的是,在使用wsimport工具生成client.TempServer- ImplService时,像与服务对应的Qname和服务端点等这些复杂的细节都被隐藏掉了。下

    面是针对采用基于WSDL协议所生成的相关工件(Artifact)编写服务客户端的一些常用做法,比如像这里的TimeServer和TimeServerImplService。

    首先,通过wsimport产生的Class中的一个或两个构造方法构造一个服务对象,比如在本例的client.TimeServerImplService类中。无参数的构造方法更可取,因为这样更为简单。然而,在本例中,还是生成了一个拥有两个输入参数的构造方法,用来适应Web服务的命名空间(URI)或服务端点(RUL)的变化。当然还可以通过wsimport工具包重新生成基于WSDL的Java文件,用在其他客户端开发中。

    通过构建的服务对象调用对应的get系列方法,在本例中是getTimeServerImplPort方法。这个方法返回一个封装了Web服务操作方法的对象,本例中分别是定义在目标SEI中的getTimeAsString和getTimeAsElapsed方法。

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读