cxf osgi

先决条件

首先下载并安装 Eclipse 3.5(Galileo)。Eclipse 3.5 包含了一个叫作 Equinox的 OSGi 框架

然后下载 cxf-dosgi 单包发行版和 osgi compendium 包。下载这两个包并保存到本地的同一个目录中。

下载并安装 Apache Tomcat 5.5.9。我们将使用在 OSGi 容器(Eclipse)外部的 servlet 容器,用来安装和运行我们的服务客户机。

准备 OSGi 容器

在开发一个分布式服务包之前,首先启动容器并把 cxf-dosgi 注册为服务提供商 enabler,从而为 OSGi 容器做准备。

使用一个空的工作空间启动 Eclipse 3.5。把 Perspective 设置为 “Plug-In Development”。一个 Eclipse 插件基本上就是一个 OSGi 包。

接下来使用菜单选项导入 cxf-dosgi osgi compendium 包以及 osgi compendium 包:

File/Import/Plug-In Development/Plug-ins and Fragments

然后选择下载包所在的目录。请参见 。


图 1. 导入所需的包。指定目录位置
指定目录位置

单击 Next。在下一个对话框中,Eclipse 会显示已下载的包。请参见 。


图 2. 导入所需的包,选择已下载的包
选择已下载的包

单击 Add All 和 Finish。Eclipse 会自动创建两个 Plug-In Development 项目,叫作 org.osgi.compendium 和 cxf-dosgi-ri-singlebundle-distribution。接下来我们需要把 osgi compendium 包作为所需的包指定到 dosgi 包中。双击 cxf-dosgi-ri-singlebundle-distribution 项目中的 META-INF/MANIFEST.MF 文件。当 Eclipse 在设计模式中打开清单文件时,选择 Dependencies 选项卡,然后添加 org.osgi.compendium 作为 “Required Plug-ins”。现在您的 Eclipse 环境应该如 t--3所示。


图 3. 导入所需的包
所需的包

OSGi 容器现在已经为一些分布式服务部署做好了准备。

开发一个服务包

接下来,我们将使用一个方法创建一个基于 POJO 的简单 Web 服务,叫作 DictionaryService。这个方法就是 lookupWord(string),它能返回一个字符串(单词的含义)作为响应。

要在 Eclipse 中创建一个服务包,首先要确保 Perspective 被设置为 “Plug-in Development”。创建一个叫作 DictionaryService 的新 Plug-in 项目。在创建项目时,选择 com.demo.cxfdemo.Activator 作为包结构。您可以在附带包(cxf-dosgi-dw-article.zip 文件中的 DictionaryService_1.0.0.200908011529.jar)

Activator.java, DictionaryService.java and DictionaryServiceImpl.java,使用它们替换由 Eclipse 创建的默认的 Activator.java。双击 DictionaryService 项目中的 META-INF/MANIFEST.MF。Eclipse 应该会显示清单文件的设计视图。单击 Dependencies 选项卡,清除 Required Plug-ins,然后在 Imported Packages 中添加 org.osgi.framework。您的 Eclipse 会如下面的 所示。


图 4. 创建一个服务包
服务包

Activator.java, DictionaryService.java and DictionaryServiceImpl.java 所示。


清单 1. DictionaryService 包代码

				
package com.demo.cxfdosgi;

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

public class Activator implements BundleActivator {

    private ServiceRegistration registration;

    public void start(BundleContext bc) throws Exception {
	    Dictionary<String, String> props = new Hashtable<String, String>();
	    props.put("osgi.remote.interfaces", "*");
	    props.put("osgi.remote.configuration.type", "pojo");
	    props.put("osgi.remote.configuration.pojo.address", 
                  "http://localhost:9000/DictionaryService");    
	
	    registration = bc.registerService(DictionaryService.class.getName(), 
	                                      new DictionaryServiceImpl(), props);	
	}

    public void stop(BundleContext context) throws Exception {
        registration.unregister();
    }
}

package com.demo.cxfdosgi;

public interface DictionaryService {
	
	public String lookupWord(String word) throws Exception;

}

package com.demo.cxfdosgi;

public class DictionaryServiceImpl implements DictionaryService {

	public String lookupWord(String word) throws Exception {
		return word + " means...";
	}

}

我们的 Web 服务基本上就是一个 pojo(接口和实现)。Activator 类设置服务属性并注册服务。特别值得一提的是,DictionaryService 不必实现或扩展任何 cxf 类。我们甚至不必把 dosgi 单包设置为一个必需的插件。通过应用 cxf-dosgi,在执行 Run 配置时,它将被作为一个 cxf Web 服务进行部署。

部署服务包

下一步是部署和运行服务包。为此,我们需要创建一个 Run Configuration。右键单击 DictionaryService 项目,然后选择 Run As/Run Configurations。在名为 demo_dosgi 的 OSGi Framework 文件夹中创建一个新的配置。您的 Run Configuration 弹出对话框应该如  所示。


图 5. Run 配置
Run 配置

单击 Apply 和 Run。现在 Eclipse 会启动它内部的 OSGi 框架(Equinox),安装和启动工作空间的三个包。您的 Eclipse 环境现在应该如 所示。


图 6. 运行包
运行包

注意,Eclipse 不会自动显示 osgi> 提示。单击一下 Console 窗口会得到此提示。在这个提示中运行命令 ss(短暂状态),查看包的状态。要获得其他可用命令清单,在提示中运行 ?。上面的显示也可以确认服务端点 URLhttp://localhost:9000/DictionaryService 是否可用。还可以通过在浏览器中运行 URLhttp://localhost:9000/DictionaryService?wsdl 来确认这一点,现在这个浏览器应该显示 WSDL 内容。把这个 xml 文档作为DictionaryService.wsdl 保存到一个临时文件夹中。在下一小节,我们将使用它生成一个客户机。

开发 Web 客户机以调用服务

要调用新部署的 Web 服务,现在让我们创建一个简单的 Web 应用程序客户机。在 Eclipse 中切换到 Java EE Perspective,创建一个叫作 DictionaryServiceClient 的新的 Dynamic Web Application 项目。把 DictionaryService.wsdl 复制到 WebContent 文件夹中。右键单击 DictionaryService.wsdl 文件,然后选择 Web Services/Generate Client。现在 Eclipse 应该已经在包名为com.demo.cxfdosgi 的 src 文件夹中创建了一组客户机 Java 文件。现在我们创建一个 jsp 文件 dictionaryServiceClient.jsp,用来调用这个服务代理,如下面的 所示:


清单 2. dictionaryServiceClient.jsp 代码

				
		
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" 
import="com.demo.cxfdosgi.DictionaryServicePortTypeProxy"%>

<html>
<body>
<%
DictionaryServicePortTypeProxy proxy = new 
DictionaryServicePortTypeProxy();
out.println("?? DictionaryService response = 
"+proxy.lookupWord("whatisthis"));
%>
</body>
</html>

右键单击 DictionaryServiceClient 项目,然后导出一个 war 文件 DictionaryServiceClient.war。把这个文件复制到 C:/jakarta-tomcat-5.5.9/webapps 文件夹中。运行 C:/jakarta-tomcat-5.5.9/bin/startup.exe,然后访问http://localhost:8082/DictionaryServiceClient/dictionaryServiceClient.jsp。浏览器将显示:

?? DictionaryService response = whatisthis means...  

由于 Eclipse 和 Tomcat 在两个不同的 JVM 中运行,我们已经用一个分布式客户机测试了服务包。注意:把 Tomcat 的 HTTP 端口设置为 8082,这是因为 Eclipse 已经在使用 8080 部署 cxf Web 服务。

新版的服务包

把 Web 服务作为一个 OSGi 包进行部署的一个有趣功能就是可以同时部署一个 Web 服务的多个版本。现在让我们开发 DictionaryService 的下一个版本:DictionaryServiceV2。DictionaryServiceV2 的 lookupWord 方法能够返回两个字符串数组,一个表示单词的释义,另一个包含该词的同义词。由于我们修改了方法签名,显然已经破坏了现有客户机。通过把修改后的 Web 服务作为一个独立的包进行部署,我们使旧客户机能够继续运行,同时使新客户机能够使用服务的新版本。

在 Eclipse 中切换到 Plug-in Development Perspective,使用三个文件创建一个叫作 DictionaryServiceV2 的新的 Plug-in 项目。这三个文件分别是 Activator.java、DictionaryServiceV2.java 和 DictionaryServiceV2Impl.java,源代码如下所示:


清单 3. DictionaryServiceV2 包代码

				

package com.demo.cxfdosgi.v2;

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

public class Activator implements BundleActivator {

    private ServiceRegistration registration;

    public void start(BundleContext bc) throws Exception {
	    Dictionary<String, String> props = new Hashtable<String, String>();
	    props.put("osgi.remote.interfaces", "*");
	    props.put("osgi.remote.configuration.type", "pojo");
	    props.put("osgi.remote.configuration.pojo.address", 
                  "http://localhost:9000/DictionaryServiceV2");    
	
	    registration = bc.registerService(DictionaryServiceV2.class.getName(), 
	                                      new DictionaryServiceV2Impl(), props);	
	}
    
    public void stop(BundleContext context) throws Exception {
        registration.unregister();
    }
}

package com.demo.cxfdosgi.v2;

public interface DictionaryServiceV2 {
	
	/**
	 * @param word - String, whose meaning and synonyms are requested
	 * @return String[] - where String[0] has the word meaning and 
     *                          String[1] has synonyms
	 * @throws Exception
	 */
	public String[] lookupWord(String word) throws Exception;

}

package com.demo.cxfdosgi.v2;

public class DictionaryServiceV2Impl implements DictionaryServiceV2 {

	public String[] lookupWord(String word) throws Exception {
		// TODO Auto-generated method stub
		String[] result = new String[2];
		
		result[0] = word + " means...";
		result[1] = "Synonyms:...";
		
		return result;
	}

}

您的 Eclipse 窗口应该如 所示。


图 7. 创建 DictionaryServiceV2 包
DictionaryServiceV2 包

编辑 demo_dosgi Run 配置,确保配置中包含了 DictionaryServiceV2 包,如 所示。


图 8. 修改后的 Run 配置
Run 配置

单击 Apply 和 Run。现在 Eclipse 会重新启动 OSGi 框架,安装第四个包(DictionaryServiceV2),然后启动所有的四个包。现在您的 Eclipse 会如 所示。


图 9. 运行包
运行包

这将确认所有的四个包都已安装并且正在运行。日志消息也可以确定服务端点:

http://localhost:9000/DictionaryService 和

http://localhost:9000/DictionaryServiceV2

处于激活状态。在浏览器中访问第二个服务,如 http://localhost:9000/DictionaryServiceV2?wsdl,然后把显示的 wsdl 内容保存到文件 DictionaryServiceV2.wsdl 中。

调用新服务

要调用新版本的 Web 服务,我们需要生成一个新的客户机。创建一个新的项目 DictionaryServiceV2Client 作为一个 Dynamic web Application。使用与第一个版本相同的步骤复制 wsdl 并生成 Java 客户机。创建一个新的 jsp 文件dictionaryServiceV2Client.jsp,如:


清单 4. dictionaryServiceV2Client.jsp 代码

				

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" 
import="com.demo.cxfdosgi.v2.DictionaryServiceV2PortTypeProxy"%>

<html>
<body>
<%
DictionaryServiceV2PortTypeProxy proxy = new 
DictionaryServiceV2PortTypeProxy();
String[] resp = proxy.lookupWord("whatisthis");
out.println("?? DictionaryService response = "+resp[0]);
%>
<br/>
<%
out.println("?? DictionaryService response = "+resp[1]);
%>
</body>
</html>

把这个项目作为 DictionaryServiceV2Client.war 导出,然后把它安装到运行在 Eclipse 外部的 tomcat 服务器中。现在在浏览器中访问 http://localhost:8082/DictionaryServiceV2Client/dictionaryServiceV2Client.jsp 时应该显示为:

?? DictionaryService response = whatisthis means...  
?? DictionaryService response = Synonyms:...

现在我们已经成功地开发、部署和测试了一个 Web 服务的两个版本。

结束语

在本文中,我没有使用 pojo 服务包中的任何 cxf-dosgi API 类。然而,可以通过编辑 manifest.mf 文件(前面的 “导入包” 部分),导入指定包来使用 cxf-dosgi 类。注意,所有 J2SE 类本质上说都可用于一个包。但是,要从一个服务包中使用任何 JEE 服务(如发送邮件等),您需要通过编辑 manifest.mf 来导入具体的 JEE 包。Eclipse 提供了大部分可导入的 JEE 包。

我已经描述了把 Web 服务作为一个 OSGi 包进行开发和部署以及使用一个简单的 web 应用程序客户机调用服务的详细方法。我还讨论了 SOA 策略对于在一个整洁的 OSGi 容器环境中同时部署和支持一个服务的多个版本的好处。

猜你喜欢

转载自ssydxa219.iteye.com/blog/1329194
CXF