`

利用 WAS 6.1 WebService 功能部件包开发 JAX-WS 2.0 Web services

 
阅读更多

引言

JAX-WS 2.0 的全称为 Java API for XML-Based Web services (JAX-WS) 2.0。JAX-WS 2.0 是对 JAX-RPC 1.0 规范的扩展,是 JAX-RPC 1.1 的后续版本, JAX-RPC 2.0 标准发布不久后便被重新命名为 JAX-WS 2.0。 JAX-WS 2.0 是面向 Java 5 的开发 Web services 的最新编程标准,它提供了新的编程模型和对以往的 JAX-RPC 方式的 Web services 进行了增强。在 WebSphere 应用服务器 6.1 Web services 功能部件包中提供了对 JAX-WS 2.0 的支持。本文结合 WebSphere 里的开发工具 AST(Application Server Toolkit) 讲述了 JAX-WS 2.0 标准下 Web services 的开发过程,同时介绍了 JAX-WS 2.0 一些重要的 API 和命令行工具 wsimport,wsgen 的使用。本文对于想了解 Web services 最新变化和准备采用 JAX-WS 2.0 编程的相关人员有一定的帮助。

 




回页首

 

JAX-WS 2.0 介绍

和以往的 JAX-RPC 相比,JAX-WS 2.0 的主要特点有:

  • 新的 API 和新的编程模型。新的 API 主要包含在 javax.xml.ws 包中,包括 service 端和 client 端的一些核心类。新的编程模型包括增强的 Handler Framework,异步调用和 Provider/Dispatch 动态编程模型。
  • 采用 annotations 来描述 Web services,不再依赖部署以往的 Web service 描述文件。
  • 通过 JAXB 2.0 完成 xml data 和 Java 对象的绑定,改变了 JAX-RPC 1.0 里同时存在两套 binding 机制的不便。
  • MTOM/XOP(SOAP Message Transmission Optimization Mechanism/XML Binary Optimized) 和 swaRef(SOAP Attachment Refenreces),解决了在 SOAP 消息里传输二进制附件的问题,同时对消息传输进行了优化。
  • 对 SOAP 1.2 的支持。
  • 针对上述特点,Web services 功能部件包主要在以下几个方面提供了相应的支持:
  • 在 WAS(WebSphere Application Server) runtime 中增加了对 JAX-WS 2.0 的支持 , 使得基于 JAX-WS 2.0 的 Web services 能在 WAS 中部署运行。
  • 新增了用于创建 JAX-WS 2.0 应用的一些命令行工具,如 wsimport 和 wsgen。
  • 在 AST 中增加了开发 JAX-WS 2.0 应用的插件。

此外,功能部件包同时提供了对其它如 JAXB_2.0, MTOM/XOP API 以及基于 PolicySet 安全化 Web services 等高级特性的支持。

 




回页首

 

JAX-WS 2.0 开发过程

同 基于 JAX-RPC 的 Web services 一样,JAX-WS 2.0 的开发分为 service 端和 client 端。在 service 端,可以选择自顶向下或自底向上的方式来创建 Web services,这两种方式可以通过 AST 或命令行工具来完成。在 client 端,一般通过 AST 或命令行工具根据 WSDL 文件创建用于调用 Web services 的辅助类,然后再在自己的代码中使用这些辅助类。 JAX-WS 2.0 提供了多种 client 端的编程模型。下面将分别介绍 service 端和 client 端的开发过程。

Service 端的开发

JAX-WS 2.0 有两种开发过程 : 自顶向下和自底向上。自顶向下方式指通过一个 WSDL 文件来创建 Web services,自底向上是从 Java 类出发创建 Web services。两种开发过程最终形成的文件包括:

  • SEI(service endpoint interface)。一个 SEI 对应 WSDL 中 Web service 的一个 port,在 Java 中是一个 Java 接口。
  • SEI 实现类。
  • WSDL 和 xsd 文件。

Web services 既可以包含在一个 web module 中发布,也可以包含在 EJB module 中发布。下面我们结合实例来看一个自顶向下的 Web services 的开发过程。该例子包含的 Web services 很简单:一个 service,该 service 只有一个 port,该 port 只有一个操作 addNumber。

首先,我们开发一个普通的 Java Bean。在 AST 中创建两个项目:一个动态 web 项目,包含我们示例的 Web services;另一个 J2EE 项目,用于生成 ear。

清单 1. 用于创建 Web service 的一个普通 Java Bean

package com.ibm.ws.demo.server;

public class SimpleBean {
	public int addNumber(int i , int j) {
return i + j;
	}
}

 

在 AST 工具中,选中该类,在右键弹出菜单中,启动 Web service 创建向导。在向导中,您需要选择 Web services 运行时的 runtime 为 IBM WebSphere JAX-WS。同时,选择生成 WSDL 文件。其余步骤按缺省设置。

最后生成的项目结构如下:


上 图中,SimpleBeanDelegate.java, AddNumber.java 和 AddNumberResponse.java 为向导生成的 java 类,WebContent 下还生成了两个 Web service 的描述文件 SimpleBeanService.wsdl 和 SimpleBeanService_schema1.xsd。

在 AST 中导出 ear 文件,在 WebSphere 管理控制台上部署,再启动应用。在浏览器中通过下面形式的 URL 可以验证 Web services 是否成功启动。

http://hostname:port/webmodule/QName

注意 AST 中自动生成的一个代理类 SimpleBeanDelegate.java:

清单 2. 用于部署 Web service 的代理类 SimpleBeanDelegate.java

import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.jws.soap.SOAPBinding;

@WebService (targetNamespace="http://server.demo.ws.ibm.com/", 
 serviceName="SimpleBeanService", 
 portName="SimpleBeanPort", 
 WSDLLocation="WEB-INF/WSDL/SimpleBeanService.WSDL")
public class SimpleBeanDelegate{

 SimpleBean _simpleBean = new SimpleBean();

 public int addNumber(int i, int j) {
 return _simpleBean.addNumber(i,j);
 }

}

 

上面这个类是真正用于部署 Web services 的类,该类采用了 Annotation 来描述 Web services。 Annotation 是 Java 5 的一大语言特性,采用 Annotation 描述 Web services 的元数据,减轻了开发者的部署负担。在 javax.jws 包中定义了如下主要的 Annotation:

  • javax.jws.WebService
  • javax.jws.WebMethod
  • javax.jws.WebParam

Client 端的开发

客 户端开发的通常过程是从已有的 WSDL 出发,创建辅助类 JAXB 对象和 service 代理类,然后基于这些类开发自己的客户端应用。在 AST 中,选中工程 SimpleJaxWS 下的 WSDL 文件 SimpleBeanService.WSDL,在右键菜单中启动 Web services 客户端创建向导。在创建过程中,同样需要选择 runtime 为 IBM WebSphere JAX-WS, 其它按默认设置。最终生成的客户端项目结构如下:


其 中自动生成的 Java source 包括 JAXB 对象 , 如上图中的 AddNumber.java,AddNumberResponse.java, ObjectFactory.java 以及 package-info.java 类,和 service 代理类,如上图中的 SimpleBeanDelegate.java, SimpleBeanPortProxy.java 以及 SimpleBeanService.java 类。然后,再写一个测试类 WSClient.java,该类是一个独立运行的 Java application。测试时,您需要在 classpath 中添加一个 thin client:com.ibm.jaxws.thinclient_6.1.0.jar。该 jar 在 $WAS_HOME/runtimes 目录下可以找到。

清单 3. 调用 Web service 的客户端 WSClient.java

public class WSClient {

	QName serviceName = new QName("http://server.demo.ws.ibm.com/",
			"SimpleBeanService");
QName portName = new QName("http://server.demo.ws.ibm.com/",
			"SimpleBeanPort");

	String host = "9.186.117.142" ;
	String port = "9080" ;

	String endpt ;
	String WSDLURL ;
	SimpleBeanService service = null;


	public WSClient() {

		endpt = "http://"+ host +":" + port +"/SimpleJaxWS/SimpleBeanService" ;
		WSDLURL = "http://"+ host +":" + port 
			+ "/SimpleJaxWS/SimpleBeanService/WEB-INF/WSDL/SimpleBeanService.WSDL" ;
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|


|-------- XML error:  The previous line is longer than the max of 90 characters ---------|



	}

	/**
	 * Get the SEI from endpoint address
	 * @param endpt
	 * @return
	 */
	public SimpleBeanDelegate getSEIFromEndpoint() {

		SimpleBeanDelegate port = null ;
		BindingProvider p = null;

		try {			
			service = new SimpleBeanService(null, serviceName);
			System.out.println("Looking up service "
				+ service.getServiceName());

			port = service.getSimpleBeanPort();
			p = (BindingProvider) port;
			p.getRequestContext().put(
				BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpt);
			//p.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|


|-------- XML error:  The previous line is longer than the max of 90 characters ---------|


			//p.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, "invoke"); 
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|


|-------- XML error:  The previous line is longer than the max of 90 characters ---------|




		} catch (Exception e) {
			e.printStackTrace() ;
		}		
		return port ;

	}



	public void simpleCall() {

		try {			

			SimpleBeanDelegate port = getSEIFromEndpoint() ;		
			System.out.println(port.addNumber(8, 9));			

		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	public static void main(String[] args) {		

		WSClient client = new WSClient() ;		
		client.simpleCall() ;


	}

 

客户端调用 Web service 的常见过程为:先创建一个 service 对象,再从 service 对象获得 SEI,最后调用 SEI 的方法去访问 Web service。

Web services 客户端的异步调用方式

除 了上述的同步调用方式外,JAX-WS 2.0 还提供了异步调用,采用异步调用,客户端不需要等待 SOAP response 消息的返回,就可以继续别的处理。异步调用方式有 polling 和 callback 两种,这里只讲 callback 方式。 callback 就是提供一个 callback 函数,供消息返回时调用。在 Java 中,该 callback 函数是一个实现了特定接口的类。如果要异步方式访问 Web services,首先得在 SEI 中生成一个异步调用的方法。在用 AST 中的 Web services 向导工具创建 Web services 客户端时,注意选中“生成异步调用方法”:

生成的异步调用方法如下:

清单 4. 用于异步调用 Web service 的方法定义

@WebMethod(operationName = "addNumber")
 @RequestWrapper(localName = "addNumber", 
		targetNamespace = "http://server.demo.ws.ibm.com/", 
		className = "com.ibm.ws.demo.client.AddNumber")
 @ResponseWrapper(localName = "addNumberResponse", 
		targetNamespace = "http://server.demo.ws.ibm.com/", 
		className = "com.ibm.ws.demo.client.AddNumberResponse")
 public Future < ? > addNumberAsync(
 @WebParam(name = "arg0", targetNamespace = "")
 int arg0,
 @WebParam(name = "arg1", targetNamespace = "")
 int arg1,
 @WebParam(name = "asyncHandler", targetNamespace = "")
 AsyncHandler < AddNumberResponse > asyncHandler);

 

当 SOAP response 返回时,客户端 runtime 会调用我们提供的 AsyncHandler。下面是一个实现了 AsyncHandler 的类。

清单 5. 用于异步调用 Web service 的 Handler 类,处理返回的 SOAP 消息

import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;

public class CallbackHandler implements AsyncHandler <AddNumberResponse>{

	public void handleResponse(Response response) {

		AddNumberResponse res = (AddNumberResponse)response ;
		//do something with the response...
		System.out.println("Response result is : " + res.getReturn());
	}
}

 

最终,客户端异步调用 Web services 的形式为:

清单 6. 异步调用 Web service 的代码

public void asyncCall() {

	try {			

		SimpleBeanDelegate port = getFromJavaBeanImpl(endpt) ;
		CallbackHandler asyncHandler = new CallbackHandler() ;
		port.addNumberAsync(8, 9, asyncHandler) ;		

		//do other things...

	} catch (Exception e) {
		e.printStackTrace();
	}
}

 

Provider/Dispatch 编程模型

JAX-WS 2.0 还提供了 service 端和 client 端的动态编程模型:Provider/Dispatch 模型。Provider<T> 和 Dispatch<T> 分别是 service 端和 client 端提供的两个接口,该编程模型可以让您在 xml message 级别上工作。换言之,您可以通过编程操纵整个 SOAP 信封或 SOAP 信封的 body。 T 的类型和另一个参数 Service.Mode 组合在一起,决定了操作的 xml message 到底是整个 SOAP 信封还是部分。T 的两种类型为 Source 和 SOAPMessage,两种 Service 模式为 Service.Mode.MESSAGE 和 Service.Mode.PAYLOAD。下面给出了其中一种组合的示例。

Service 端的代码示例

清单 7. 以 Provider 模式实现 Web service 的 service 端 Java 类

@WebServiceProvider 
@ServiceMode(value=Service.Mode.MESSAGE) 
public class ProviderImpl implements
 Provider<SOAPMessage> { 
 public SOAPMessage invoke(SOAPMessage msg) { 
		//here the msg is the entire SOAP request 
		// do request processing
		SOAPMessage response = ...; 
		return response; 
 } 
 }

 

Client 端的代码示例

清单 8. 以 Dispatch 模式调用 Web service 的 client 端 Java 类

//create the service
Service service = Service.createService(QName serviceQName);
//or Service service = Service.createService(URL WSDLLocation, QName serviceQName);
//set the binding
service.addPort(QName portName, String SOAPBinding.SOAP11HTTP_BINDING, 
 String endpointAddress);
//create the dispatch
Dispatch dispatch = service.createDispatch(QName portName, Class clazz, 
 Service.Mode mode);
//Dispatch dispatch = service.createDispatch(QName portName, JAXBContext jaxbcontext, 
 Service.Mode mode);

//invoke the Web services
Object response = dispatch.invoke(T);
dispatch.invokeOneway(T);
//or Response<T> response = dispatch.invokeAsync(T);
//or Future<?> response = dispatch.invokeAsync(T, AsyncHandler);

 

这里的问题是如何生成类型 T 的实例,答案是通过 JAXB 标准提供的 API 将 Java object 转化为 xml message 对象。

 




回页首

 

通过 wsgen,wsimport 工具创建 Web services

除 了 AST 中提供的图形界面开发方式外,Web services 功能部件包还提供了创建 Web services 的命令行工具。其中,wsgen 支持从 Java class 创建 Web services,wsimport 支持从 WSDL 创建 Web services。分别对应于 JAX-RPC 方式下的 Java2WSDL 和 WSDL2Java。

清单 9. wsgen 命令格式

wsgen [options] < SEI >

主要选项:

  • -d 指定生成的 class 文件的位置。
  • -s 指定生成的 Java source 文件的位置。
  • -r 指定生成的 resources 文件的位置。如 WSDL,xsd 的位置。
  • -WSDL,-servicename,-portname 三个参数指定生成的 WSDL 文件中的 service 和 port 的名称。

注 意:这里的 SEI 是一个 endpoint implementation class,而不是一个接口。你必须先写好一个 endpoint 的实现类,如上面的 SimpleBeanDelegate,该类中用 @WebService 声明好 Web service,再将它编译成 class 文件,才能提供给 wsgen 使用。

清单 10. wsgen 使用实例

wsgen.sh -cp classes -s src -d bin -r web -WSDL com.ibm.ws.demo.server.SimpleBeanDelegate

 

清单 11. wsimport 命令格式

wsimport [options] <WSDL_URI>

主要选项:

  • -d 指定生成的 class 文件的位置。
  • -s 指定生成的 Java source 文件的位置。
  • -WSDLlocation 指定生成的 Java source 中 @WebService.WSDLLocation 和 @WebServiceClient.WSDLLocation 的值。

清单 12. wsimport 使用实例

wsimport.sh -d classes -s src -WSDLlocation /WEB-INF/WSDL/SimpleBeanService.WSDL 
 SimpleBeanService.WSDL 

 




回页首

 

通过 Ant task 自动构建 Web services 应用

WebSphere 同时提供了用于创建 Web services 的 ant task,这些 task 的参数和 wsgen,wsimport 是一致的。利用这些 ant task,您可以在大型项目中完成自动构建工作。

清单 13. 在 Ant 中使用 wsgen 和 wsimport

<wsgen sei="..."
 destdir="directory for generated class files"
 classpath="classpath"
 resourcedestdir="directory for generated resource files such as WSDLs"
 sourcedestdir="directory for generated source files" 
 keep="true|false" verbose="true|false"
 genWSDL="true|false" protocol="soap1.1|soap1.2"
 servicename="..."
 portname="..."
 extension="true|false">
 <classpath refid="..."/>
</wsgen>

<wsimport WSDL="..." 
	destdir="directory for generated class files" 
	sourcedestdir="directory for generated source files" 
	keep="true|false" extension="true|false" 
	verbose="true|false" version="true|false" 
	WSDLLocation="..." 
	catalog="catalog file" 
	package="package name">
	<binding dir="..." includes="..." />

</wsimport>

 

结束语

本 文向您讲述了 JAX-WS 2.0 的主要特性,并通过示例展示了 Web services 新的编程模型和 API 及其开发过程。通过本文,您可以对 JAX-WS 2.0 有一个初步的了解,并懂得如何通过 WebSphere 提供的工具开发简单的符合 JAX-WS 2.0 的 Web services。值得说明的是,本文并没有向您介绍 JAX-WS 2.0 的全部特性,您可以通过本文提供的参考资源获得更多信息。



参考资料

学习


获得产品和技术


讨论
参与 developerWorks Blog ,从而加入到 developerWorks 社区中来,其中包括以下与 SOA 和 Web 服务相关的 Blogs:

分享到:
评论

相关推荐

    设计与开发 JAX-WS 2.0 Web 服务

    通过使用 Java™ API for XML Web Services (JAX-WS) 技术设计和开发 Web 服务,可以带来很多好处,能简化 Web 服务的开发和部署,并能加速 Web 服务的开发。通过此教程,可以了解如何开发将其功能作为 Web 服务公开...

    webService部署tomcat需要的jax-ws jar包

    webService部署tomcat需要的jax-ws 的完整jar包

    jax-ws webservice demo

    基于jax-ws 实现的web service client和server端的demo程序。 注:如果使用的是 myeclipse 时 server 部署到tomcat 启动的时候会报错 解决办法:找到myeclipse安装目录下的 plugins 目录里 查找 webservices-rt.jar,...

    Asynchronous Web Service Invocation with JAX-WS 2.0

    Asynchronous Web Service Invocation with JAX-WS 2.0

    jax-ws 2.0文档说明以及源码

    jax-ws webservice类简介开发,包含文档以及源码,谢谢支持!get get get

    如何基于JAX-WS开发一个WebService实例

    NULL 博文链接:https://liuyunlong1229.iteye.com/blog/1678559

    webservice需要的jar包JAX-WS2.1.4.rar

    严重: Error configuring application listener of class com.sun.xml.ws.transport.http.servlet.WSServletContextListener java.lang.ClassNotFoundException: ...

    Jax-ws所需要的JAR包

    亲测可用,Jax-ws所需要的JAR包,拷贝到tomcat安装路径的lib里,实现了webservice发布到tomcat,赞!

    MyEclipse8_0中使用 JAX-WS 部署 WebService 实例

    MyEclipse8_0中使用 JAX-WS 部署 WebService 实例 - 外衣 - 博客频道 - CSDN_NET.mht

    JAX-WS_WebService.rar

    JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用

    jax-ws webservice简单demo

    jax-ws webservice完整demo,包含所有jax-ws 2.2jar包。

    JAX-WS自学笔记

    JAX-WS自学笔记 本人自学JAX-WS笔记和简单例子,文档标题结构如下: JAX-WS使用教程 1、JAX-WS概述 2、创建Web Service 2.1 从java开始 2.1.1 运行wsgen 2.1.2 生成的WSDL和XSD 2.1.3 目录结构 2.2 从WSDL...

    jax-ws创建webservice

    利用myeclipse创建的 jax-ws demo

    jax-ws发布webservice

    以jdk1.6以上自带的jax-ws来发布webservice,压缩包里包含服务端和客户端,下载导入即可启动运行测试,有疑问的话欢迎咨询哈

    使用JAX-WS(JWS)发布WebService

    使用JAX-WS(JWS)发布WebService 使用myeclipse开发java的webservice的两种方式 方式一: (此方式只能作为调试,有以下bug:jdk1.6u17?以下编译器不支持以Endpoint.publish方式发布document方式的soap,必须在...

    WebService之JAX-WS自学笔记

    自己自学JAX-WS的心得,内含较为详细的讲解了简单的例子。文档目录如下: JAX-WS自学笔记 本人自学JAX-WS笔记和简单例子,文档标题结构如下: JAX-WS使用教程 1、JAX-WS概述 2、创建Web Service 2.1 从java...

    基于JAX-WS2.2开发WebService所需jar资源包

    使用 Eclipse JavaEE 开发 WebService 时,若选择手动创建原生的JAX-WS服务,需要导入此jar资源(教程详见我的博文https://blog.csdn.net/weixin_50604409/article/details/116399530)。 如果您同时装有 IntelliJ ...

    JAX-WS 2.2 完整jar包

    JAX-WS 2.2 RI 所包含的JAR包集合,包含25个JAR包,列表如下: FastInoset.jar gmbal-api-only.jar ha-api.jar javax.annotation.jar javax.mail_1.4.jar jaxb-api.jar jaxb-impl.jar jaxb-xjc.jar jaxws-api...

    webservice Demo注解+jax-ws

    对webservice入门是很好的例子 使用webservice注解 基于jax ws jdk自带实现 知识点在readme txt中有详细介绍

    JAX-WS开发的文件生成与部署相关全视频过程

    如果基于一个JAX-WS进行WebService开发,有很多教程,但是具体怎么更自动地生成一些文件,实现客户端与服务端的交互,都讲得不大清楚,为了让大家更方便地部署,我将服务端、客户端文件的生成与部署全过程以及测试...

Global site tag (gtag.js) - Google Analytics