第二章 基于JAX-WS开发Web services

基于JAX-WS开发Web services

这篇文章纯属搬砖。

转载于:http://www.ithov.com/linux/125942_4.shtml。



  Web Services 是一种面向服务的技术,通过标准的 Web 协议提供服务,目的是保证不同平台的应用服务可以互操作。依据 web services 规范实施的应用之间,无论它们所使用的语言、 平台或内部协议是什么,都可以相互交换数据,这就是 web services 的好处。本文选择 IBM WebSphere Application Server 作为 web services 的运行环境,并选择 IBM Rational Application Developer(以下简称 RAD)for WebSphere 就是作为本文的开发平台。RAD 针对 IBM WebSphere Application Server 的测试环境进行了优化,减少了开发人员因配置环境而消耗的时间。本文中展示的所有示例都是在 RAD for WebSphere 平台上开发、测试的。

Web Services 与 JAX-WS

  Web Services 发展至今已有两种形式:REST 和 SOAP。REST Web Services 基于 HTTP 协议,SOAP Web Services 支持多种传输协议:HTTP、SMTP、MIME 等等。

  本文主要介绍 SOAP web services。对于 JAVA,目前有两种 SOAP Web Services 规范:JAX-WS 和 SAAJ。

  SOAP Web Services 通常要求服务器端提供一個机器可读的描述(通常基于 WSDL),以便客户端辨识服务器端提供的 Web 服务。

  JAX-WS (Java API for XML Web Services) 是一组专门用于实现 XML Web Services 的 Java API。JDK 1.6 自带 JAX-WS 版本为 2.1。不过,JAX-WS 只提供 web services 的基础功能,所以如果你希望实现 web services 的复杂功能,比如 WS-Security,WS-Policy,WS-RM 等,那就需要切换到 Apache CXF 、Metro 或者 Axis。

本文的目标对象是初次接触 web services 或者 JAX-WS 的开发人员。所以本文将分享以下内容:

  • Web Services 服务器端的开发
  • Web Services 客户端的开发
  • 基于 https 协议的 web services 通信
  • 利用 @MTOM 优化网络大数据传输

JAX-WS web services 开发

  RAD 是一个基于 Eclipse 的全功能集成开发环境(IDE),所以熟悉 Eclipse 的开发人员可以很快的上手使用 RAD 平台。

服务器端开发:

  首先,在 RAD 平台上,创建一个最简单的 web service,这个 service 只向客户端返回一个字符串 – “Hello World”。服务器端的工作流程如下:完成 web services 编写,发布 web services 生成服务描述文件(WSDL),以供客户端获取。接下来,等待客户端发来的 SOAP 请求消息,解析其中的方法调用和参数格式。根据 WSDL 和 WSML 的描述,调用相应的对象来完成指定功能,并把返回值放入 SOAP 回应消息返回给用户。

  首先在 RAD 中新建一个 Web Project – WebProjectDemo,

图 1. 创建 Web Project

  选择相应的 Target Runtime(确认“Servers” view 中已创建 Server Runtime),并确保 “Add project to an EAR”是勾选上的,这样就不需要再手动创建 EAR 了。

图 2. 选择运行环境,完成 Project 创建

完成 Web Project 的创建。

接下来,开始编写 web service 类,开发方法很简单,只需用 @WebService 标注 Java 类为 web service 类,@WebMethod 标注类方法为 web service 方法。这些被标记的类和方法,在 service 发布之后,就能被客户端调用了。

清单 1. 服务端代码

	 @WebService
	 public class HelloWorld {
		 @WebMethod
		 public String sayHello(){
			 return "Hello World!";
	 }

简短的五行代码就是 HelloWorld web service 类啦! HelloWorld 只有一个 web service 方法 – sayHello()。

接着就是发布 HelloWorld service 了,

图 3. 发布 HelloWorld Service

发布完成,在浏览器中敲入

http://WEBSERVER:9080/WebProjectDemo/HelloWorldService?wsdl,如果能看到以下界面,就表示发布成功了。接着,我们就开始 客户端 的开发。

图 4. WSDL 文件

客户端开发 :

本文选用 Eclipse 作用客户端的开发平台,因为 RAD 内置了 WAS JRE Runtime 库,易与 JAVA JRE Runtime 冲突,所以本文就换用 Eclipse 开发客户端。

客户端的工作流程如下:取得服务器端的服务描述文件 WSDL,解析文件内容,了解服务器端的服务信息以及调用方式(生成客户端 Stub)。编写客户端 SOAP 请求消息 ( 指定调用的方法以及调用的参数 ),发送给服务器端。等待服务器端返回的 SOAP 回应消息,解析得到的返回值。

有多种生成客户端 Stub 的方式可以选择,如:axis2、jax-ws、xfire 等,不过需要注意的是各开源软件对 soap 协议解析方式不同,所以生成的的客户端也不尽然相同。本文采用 jax-ws 生成客户端 Stub,步骤如下:

  1. 首先确认从客户端机器可以访问 HelloWorld Service:
  2. http://WEBSERVER:9080/WebProjectDemo/HelloWorldService?
  3. 在 Eclipse 中,新建 Java Project – WebServiceClient
  4. 打开命令控制台,运行命令: /jdk/bin/wsimport.exe -d C:\WebServiceClient\\bin -s C:\WebServiceClient\\src – keep http://WEBSERVER:9080/WebProjectDemo/HelloWorldService?wsdl
  5. 刷新 Project,会发现 src 文件夹下多了一些文件,见图 5。 
    图 5. 客户端文件结构
  6. 修改 HelloWorldService.java 。找到

    wsdlLocation = "***.wsdl" 和 url = new URL(baseUrl, "***.wsdl") ,把 ***.wsdl 替换成

    http:// WEBSERVER:9080/WebProjectDemo/HelloWorldService?wsdl.

  7. 配置完成。现在我们就可以调用 Stub 与服务器端通信啦!新建 HelloWorldClient.java, 
    清单 2. 客户端代码
     public class HelloWorldClient {
    	 public static void main(String[] args) {
    		 HelloWorldService service = new HelloWorldService();
    		 HelloWorld proxy = service.getHelloWorldPort();
    		 System.out.println(proxy.sayHello());
    	 }
     }
    

    运行 HelloWorldClient.java,如果控制台输出“Hello World”,就表明客户端和服务器端通信成功了。

Https 与 web services

Web Services 采用网络传输数据,数据很容易暴露在外。在这种情况下,我们可以采用 Https 协议传输数据,建立一个信息安全通道,来保证数据传输的安全。当客户端与服务器端建立 https 连接时,客户端与服务器端需要经过一个握手的过程来完成身份鉴定,确保网络通信的安全。

对此,我们需要在客户端代码里做相应的处理:

  1. 利用浏览器导出 server 端证书,并保存为 demo.crt 。不同浏览器的导出步骤不一样,请查询相应的导出方法。
  2. 在客户端创建 truststore:/java/bin/keytool.exe -genkey -alias MYDOMAIN -keyalg RSA -keystore clienttruststore.jks
  3. 把 demo.crt 加入到 truststore 中: /java/bin/keytool.exe -import -trustcacerts -alias STOREALIAS -file demo.crt -keystore clienttruststore.jks
  4. 在客户端 HelloWorldClient.java 加入如下代码:

清单 3. Https 与 web services

 public class HelloWorldClient {
	 public static void main(String[] args) {
	 System.setProperty
	 ("javax.net.ssl.trustStore","PATH\\clienttruststore.jks"); //(truststore)
	 System.setProperty
	 ("javax.net.ssl.trustStorePassword", "password"); //(truststore 密码 )
	 System.setProperty
	 ("javax.net.ssl.trustStoreType", "JKS"); //(truststore 类型 ) 

		 HelloWorldService service = new HelloWorldService();
		 HelloWorld proxy = service.getHelloWorldPort();
		 System.out.println(proxy.sayHello());
	 }
 }

身份鉴定完成,可以继续 web services 的探险了。

MTOM 与 web services

我们先来了解默认情况下 SOAP 是如何传输数据的:

在 SOAP 消息中所有的二进制数据都必须以编码之后的形态存在于 XML 文件中(为避免字符冲突)。正常文本 XML 使用 Base64 对二进制数据进行编码,这就要求每三个字节对应四个字符,从而使得数据的大小增加三分之一。如果我们需要传送 10M 的文件,编码之后文件大小就 13M。这种情况下,JAVA 引入了 MTOM(消息传输优化机制)消息编码。MTOM 就是针对 SOAP 消息传输的基础上提出的改进办法。对于大量数据的传递,不会进行 Base64 编码,而是直接以附件的二进制原始数据的形式封装在 SOAP 消息的 MIME 部分,进行传输。使用 MTOM 的目的在于优化对较大的二进制负载的传输。对于较小的二进制负载来说,使用 MTOM 发送 SOAP 消息会产生显著的开销,但是,当这些负载增大到几千个字节时,该开销会变得微不足道。

现在,我们利用 MTOM 机制实现一个提供上传和下载文件功能的 HelloWorld Web Service。首先,在服务器端增加 upload() 和 download() 两个方法,并通过添加标注 @MTOM,在服务器端开启 MTOM 消息传输功能,同时选用 datahandler 类型封装传输文件。并使用 @XmlMimeType("application/octet-stream") 标注 datahandler,以表示这是一个附件类型的二进制数据。

清单 4. MTOM 服务端代码

 @MTOM
 @WebService
 public class HelloWorld {
	 private static final String REPOS = "/home/webserviceTest";
	 @WebMethod
	 public String sayHello(){
		 return "Hello World!";
	 }
	 /**
	 * 上传文件到 Server,并命名为 @fileName
	 */
	 @WebMethod
	 public String upload(
                  @XmlMimeType("application/octet-stream") DataHandler handler
                    , String fileName){
		 try {
			 File file = new File (REPOS + "/" + fileName);
			 OutputStream output = new BufferedOutputStream(
					 new FileOutputStream(file));
			 handler.writeTo(output);
			 output.close();
		 } catch (IOException e) {
			 e.printStackTrace();
		 }
		 return "Success";
	 }
	 /**
	 * 从 Server 下载名为 @fileName 的文件
	 */
	 @WebMethod
	 public @XmlMimeType("application/octet-stream")DataHandler download(
			 String fileName){
		 DataHandler dh = new DataHandler
		         (new FileDataSource(REPOS + "/" + fileName));
		 return dh;
	 }
 }

每次重新发布 web service 之后,都需要在客户端重新运行 wsimport,保持客户端 Stub 与 web service 一致。现在,我们就在客户端调用 HelloWorld 的 upload() 方法上传 test.txt 文件到服务器,并通过 download() 从 Server 下载名为 wsDemo 文件。

客户端开启 MTOM 的方式和 Server 端不同,请参见客户端代码。

清单 5. MTOM 客户端代码

 HelloWorldService service = new HelloWorldService();
 HelloWorld proxy = service.getHelloWorldPort(new MTOMFeature()); // 开启 MTOM
 File file = new File(test.txt");
 DataHandler dataHandler = null;
 dataHandler = new DataHandler(new FileDataSource(file));
 try {
    // 上传 test.txt 文件到 Server,并命名为 wsDemo
    System.out.println("Hello World Upload Function : " +
                     proxy.upload(dataHandler,"wsDemo"));
 } catch (SOAPFaultException ex) {
    System.out.println(ex.getMessage());
 }
 // 下载文件 wsDemo,并保存到本地。
 DataHandler data = proxy.download("wsDemo");
 File serverFile = new File(".\\data\\server_test.txt");
 data.writeTo(new FileOutputStream(serverFile));

我们利用 upload() 方法上传 5 个不同大小的文件 (1M,10M,50M,100M,300M),并统计上传这些文件分别消耗的时间:

图 6. Upload() 消耗时间统计
 
图 7. Upload() 消耗时间线性图

可以看出,随着文件大小的增长,上传文件所消耗的时间几乎是呈线性增长的。并且实际消耗时间和预期消耗时间(以上传 1M 文件的时间为基准,线性计算)的相差值也是在可以接受的范围内。这完全符合我们的预期期望。

结束语

本文展示利用 JAVA Web Services 规范 JAX-WS 实现 web services 客户端和服务器端通信。SOAP Web Services 使用 HTTP 传送 XML,不过由于 HTTP 的限制以及需要额外的消耗解析 XML 文件,使得 SOAP 的通信速度低于其它方案。但另一方面,XML 是一个开放、健全、有语义的讯息机制,而 HTTP 是一个广泛又能避免许多关于防火墙的问题,从而使 SOAP 得到了广泛的应用。所以,如果效率对项目是一项很重要的指标的话,就需要慎重考虑是否使用 SOAP 实现 Web Services。

时间: 2024-10-10 04:04:56

第二章 基于JAX-WS开发Web services的相关文章

xFire 开发web services

1.首先xfire 不能加紧MyEclipse10中 只能通过添加jar包的方式添加: 2.给MyEclipse6.5 添加xfire 点击 help->software updates ->find and install ->选择 search for new features to install 选择第二个  然后 下一步: 添加site  url:http://dist.codehaus.org/xfire/update/ 如图: 3.新建 web service projec

第二章:搭建Android开发环境。

第二章:搭建Android开发环境 本章主要介绍如何搭建Android底层开发的环境,主要包括Android应用程序开发环境.Android NDK 开发环境和交叉编译环境的搭建. 之前学习过一些Linux和Android的相关环境的搭建,所以Android开发环境的搭建基本上都已经了解. Andorra环境搭建的主要步骤有: 一.安装JDK 1.JDK的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

QtSoap开发web services客户端程序

首先需要下载QtSoap开源包,下载地址为: http://www.filestube.com/q/qtsoap+download, 我使用的是:qtsoap-2.6-opensource(不需要安装,直接解压到某个目录即可). 如果你从未使用过QtSoap,那么先学习其中的Demo,在目录"examples"中,有easter,google和population 三个例子. Note to Qt Visual Studio Integration users: In the inst

第二章 基于二进制进行权限管理的理论知识

源代码GitHub:https://github.com/ZhaoRd/Zrd_0001_AuthorityManagement 1.介绍 第一章主要是介绍了这个DEMO的来由和主要使用的技术,这章内容主要是介绍如何通过二进制的位运算进行权限控制的内容. 第一章发布之后,有不少网友.园友反映程序代码运行不起来,很感谢您们的反馈,刚刚进行了代码修复,已经同步到github,感兴趣的朋友可以加我QQ! 2.二进制的位运算以及如何进行权限判断 基于二进制的权限管理,这个内容是我在两年前接触到过的一个知

第二章 Android基本应用开发与解析

Andorid系统的应用开发有一个很大的特点是,通过布局XML文件来设计应用程序的界面.我们通过对Android系统资源的定义引用和对Viewd学习,以及了解各种布局和UI事件处理,从而写出有特色的应用程序 1.应用程序结构 src/目录: java原代码存放目录 gen/目录:自动生成目录,负责将图片.文字.以及布局资源自动生成一个在一个类文件中.目录中最重要的文件是R.java 这个文件由Android开发工具自动产生.Android工具会根据你放入res目录的XML界面文件.图标.常量.同

第二章:搭建Android开发环境(读后感)

在此章节中只要介绍了Android底层开发环境的搭建,其中包括了Android应用程序开发环境.Android NDK开发环境和交叉编译环境的搭建! 1:JDK的安装 (1)下载JDK的压缩包(tar.gz) http:/www.oracle.com/technework/java/javase/downloads/index.html (2)将下载的文件解压(可以解压到任何目录) (3)打开profile文件来设置PATH环境变量   # gedit  /etc/profile (4)配置PA

Qt 直接构建XML开发web services客户端程序

client.h   client.cpp     :   XML发送与接收 service.h service.cpp  :   消息的发送与接收 message.h message.cpp    :   消息的构建 messageparser.h messageparser.cpp  :   消息的解析 calc.h calc.cpp    :   计算 add.h add.cpp    :   加法运算 源代码下载:http://download.csdn.net/detail/chenj

第二章:搭建Android开发环境

1.安装JDK: 方法一:①下载JDK:②然后解压:③设置PATH环境变量#gedit /etc/profile:④输入:export PATH=.:/developer/jdk6/bin:$PATH:⑤source命令:#source /etc/profile:⑥(.)命令:. /etc/profile: 方法二:#add-apt-repository”deb http://archive.canonical.com/ lucid partner” #apt-get update #apt-g

[Maven实战-许晓斌]-[第二章]-基于UNIX系统安装maven

>>1 >>2 >>3 原文地址:https://www.cnblogs.com/whoknows1/p/9805357.html