- 浏览: 1650348 次
- 性别:
文章分类
- 全部博客 (2929)
- 非技术 (18)
- Eclipse (11)
- JAVA (31)
- 正则表达式 (0)
- J2EE (4)
- DOS命令 (2)
- WEB前端 (52)
- JavaScript (69)
- 数据库 (8)
- 设计模式 (0)
- JFreechart (1)
- 操作系统 (1)
- 互联网 (10)
- EasyMock (1)
- jQuery (5)
- Struts2 (12)
- Spring (24)
- 浏览器 (16)
- OGNL (1)
- WebService (12)
- OSGi (14)
- 软件 (10)
- Tomcat (2)
- Ext (3)
- SiteMesh (2)
- 开源软件 (2)
- Hibernate (2)
- Quartz (6)
- iBatis (2)
最新评论
打造一个Hello World OSGi Web应用程序
【51CTO精选译文】在《你好,OSGi 》的之前一篇文章 中,我们介绍 了OSGi Web应用开发工具Equinox的配置方法,在这一篇中,我们会进行Hello World OSGi Web应用程序的开发。该练习中的应用程序是一个包含了两个资源的 OSGi 套件。第一个是 helloworld.html,它是一个静态的 HTML 文件;第二个是 HelloWorldServlet,它是一个 HttpServlet。有一个重点需注意,OSGi 容器提供 HttpService 服务。每个想要处理 HTTP 请求的套件都将调用该服务上的方法来通知 OSGi 容器它能够处理哪些 URL。将 URL 注册为 OSGi 套件可处理,存在两种方式:
51CTO编辑推荐: OSGi入门与实践全攻略
程序方式:首选检索来自 OSGi 的服务寄存器 HttpService,然后调用其上的方法将请求 URL 注册为套件可处理。
声明方式:在 plugin.xml 文件中定义套件可处理的请求 URL。
我们将一步一步地对这些技巧进行讲解,先从程序注册方式开始。
程序注册方式
按照下面的步骤,可使用程序方式将 URL 注册为插件可处理。
你首先应做的是参加一个新的 OSGi 插件,命名为com.javaworld.sample.osgi.web.programmatic。(有关在 Eclipse 中创建 OSGi 插件的更多信息,请查阅本系列的第一节。)
打开 com.javaworld.sample.osgi.web.programmatic 的 MANIFEST.MF 文件并对其进行修改,导入 javax.servlet, javax.servlet.http, org.osgi.service.http 和org.osgi.util.tracker 包。更改完成之后,你的 MANIFEST.MF 应如列表 3 类似。
列表 3. 程序式插件的 MANIFEST.MF 文件
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Webapp Plug-in
Bundle-SymbolicName: com.javaworld.sample.osgi.web.programmatic
Bundle-Version: 1.0.0
Bundle-Activator: com.javaworld.sample.osgi.web.webapp.Activator
Bundle-Vendor: JAVAWORLD
Bundle-Localization: plugin
Import-Package: javax.servlet;version="2.4.0",
javax.servlet.http;version="2.4.0",
org.osgi.framework;version="1.3.0",
org.osgi.service.http;version="1.2.0",
org.osgi.util.tracker;version="1.3.2"
如你所见,Import-Package 清单头的值定义了你需要导入的包列表。
在插件的根目录创建一个简单的 helloworld.html 文件,如列表 4 所示。该文件用来显示消息“Hello From helloworld.html”。
列表 4. helloworld.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>HelloWorld OSGi Web< /title>
</head>
<body>
<h3>Hello From helloworld.html< /h3>
</body>
</html>
下一步,创建如列表 5 所示的 HelloWorldServlet。
列表 5. HelloWorldServlet
package com.javaworld.sample.osgi.web.webapp;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorldServlet extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.getWriter().println("< h3>Hello from HelloWorldServlet< /h3>");
}
}
HelloWorldServlet 类对 HttpServlet 进行扩展并重写其 doGet() 方法。新的 doGet() 方法唯一的操作就是在输出中写入“Hello from HelloWorldServlet”。
下一步,你需要在 com.javaworld.sample.osgi.web.programmatic 插件启动时执行相同的代码。Activator.java 将作为该插件的套件的激活器(Activator),如列表 6 所示。
列表 6. Activator.java
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
public class Activator implements BundleActivator {
ServiceTracker httpServiceTracker;
public void start(BundleContext context) throws Exception {
System.out.println("Hello World!!");
httpServiceTracker = new HttpServiceTracker(context);
httpServiceTracker.open();
}
public void stop(BundleContext context) throws Exception {
System.out.println("Goodbye World!!");
httpServiceTracker.close();
httpServiceTracker = null;
}
}
Activator 类对 BundleActivator 进行扩展并实现了两个方法:
start():当 OSGi 容器启动该插件时调用 start() 方法。在start()HttpServiceTracker 类 的一个对象;这是你用来跟踪 HttpService 的 ServiceTracker 类。一旦你拥有了 HttpService 类的一个对象,可以调用它的 open() 方法来开始跟踪 HttpService。
stop():当关闭插件时,OSGi 容器调用 stop() 方法。在 stop() 方法内,你调用 HttpServiceTracker 对象的 close() 方法来终止跟踪 HttpService。
最后一步是创建 HttpServiceTracker 类,如列表 7 所示。
列表 7. HttpServiceTracker
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import org.osgi.util.tracker.ServiceTracker;
public class HttpServiceTracker extends ServiceTracker{
public HttpServiceTracker(BundleContext context) {
super(context, HttpService.class.getName(), null);
}
public Object addingService(ServiceReference reference) {
HttpService httpService = (HttpService) context.getService(reference);
try {
httpService.registerResources("/helloworld.html", "/helloworld.html", null);
httpService.registerServlet("/helloworld", new HelloWorldServlet(), null, null);
} catch (Exception e) {
e.printStackTrace();
}
return httpService;
}
public void removedService(ServiceReference reference, Object service) {
HttpService httpService = (HttpService) service;
httpService.unregister("/helloworld.html");
httpService.unregister("/helloworld");
super.removedService(reference, service);
}
}
HttpServiceTracker 介绍
HttpService 是一项 OSGi 服务,允许 OSGi 环境中的套件动态的注册以及取消注册 HttpService 的 URI 名称空间中的资源和 servlet —— 换句话说,即将请求 URI 映射到一个静态 HTML 文件或一个 HttpServlet。HttpServiceTracker 类是类型 ServiceTracker 的一个对象,后者简化了对 HttpService 的跟踪。(有关 OSGi 的 ServiceTracker 的更多信息,请查阅本系列文章的第一节中的“跟踪服务”。)
列表 7 中 HttpServiceTracker 类重写了两个方法:addingService() 和 removedService()。有必要对这两个方法进行解释一下:
addingService()
一个回调方法,一旦 HttpService 可用时将对其调用。在这个方法中,首先调用
HttpService.registerResources("/helloworld.html", "/helloworld.html",
null),将 helloworld.html 文件映射到 /helloworld.html。之后,每当你请求 http://localhost/helloworld.html
时, HttpService 将为用户提供 helloworld.html。请注意,你无需将 helloworld.html 映射到
/helloworld.html URL;文件名无需匹配该地址,并且你可以将其映射到类似 /test.html 的文件上。
如果想要在你的插件中提供(serve)多个 HTML 文件,你需要创建多个目录。如果想要一个 /html 目录,可以通过调用
HttpService.registerResources("/html", "/html", null) 来注册它。然后,如果你还想要访问
html 文件夹中的 test.htm,相应的地址是 http://localhost/html/test.html
。registerServlet()
方法用于将 URL 映射到 HttpServlet 类。在这个简单的代码中,利用对
registerServlet("/helloworld", new HelloWorldServlet(), null, null) 的调用将
/helloworld URL 映射到 HelloWorldServlet 类。如需将初始化参数传递到你的
HttpServlet,你可以创建一个 java.util.Dictionary 对象并将其作为第三方自变量传递到
registerServlet()。
removedService()
每当重写你的 ServiceTracker 中的 addingService() 方法来获得一个服务时,还是重写 removedService() 来取消该服务。在 removedService() 方法内,你调用 unregister() 方法来取消注册 /helloworld.html 和 /helloworld URI。这将通知 HttpService :com.javaworld.sample.osgi.web.programmatic 不再想要为指定 URL 提供请求服务。如果你调用 unregister() 方法来取消对 servlet 的注册, 该 servlet 的 destroy() 方法将被调用以便对其自身进行清除。
现在,HelloWorld OSGi Web应用程序已经准备就绪,并且你可以在 Equinox OSGi
框架中执行你全部的套件。你应该能够通过 http://localhost/helloworld.html
访问
helloworld.html,以及通过 http://localhost/helloworld
访问 HelloWorld
的servlet。
声明注册方式
你可能已经注意到,通过程序方式将请求 URL 注册为 OSGi 创建可处理,相应的工作流并不小。而且,如果想要更改 helloworld.html 的 URL(比如从 /helloworld.html 更改到 /hello.html),你将不得不更新 HttpServiceTracker.java,重新编译代码,然后在 OSGi 容器中对其进行部署。下面,我们来看看声明方式,它稍微简单点。
1. 创建一个新的插件项目,com.javaworld.sample.osgi.web.declarative。选择 OSGi Equinox 框架作为目标平台。
2. 编辑 com.javaworld.sample.osgi.web.declarative 套件的 MANFIEST.MF 文件,导入 javax.servlet 和 javax.servlet.http 包并将 org.eclipse.equinox.http.registry 设置为该套件的被请求套件。完成这项修改之后,你的 MANIFEST.MF 文件将与列表 8 类似。
列表 8. 声明方式插件的 MANIFEST.MF 文件
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Declarative Plug-in
Bundle-SymbolicName: com.javaworld.sample.osgi.web.declarative;singleton:=true
Bundle-Version: 1.0.0
Bundle-Vendor: JAVAWORLD
Bundle-Localization: plugin
Import-Package: javax.servlet;version="2.4.0",
javax.servlet.http;version="2.4.0"
Require-Bundle: org.eclipse.equinox.http.registry
这个 Require-Bundle 清单头包含一个套件符号名的列表,在对导入搜索之后并且在套件路径搜索之前,需对其进行搜索。不过,对其请求套件,只有那些标记为通过被请求套件导出的包 才是可见的。
3. 从 com.javaworld.sample.osgi.web.programmatic 套件将 helloworld.html 和 HelloWorldServlet.java 复制到 com.javaworld.sample.osgi.web.declarative 套件。
4. 最后,更改 com.javaworld.sample.osgi.web.declarative 套件的 plugin.xml 文件,将所有请求注册为它能够处理,如列表 9 所示。
Listing 9. plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin>
<extension-point id="servlets" name="HttpService servlets" schema="schema/servlets.exsd"/>
<extension-point id="resources" name="HttpService resources" schema="schema/resources.exsd"/>
<extension-point id="httpcontexts" name="HttpService httpcontexts" schema="schema/httpcontexts.exsd"/>
<extension
id="helloServlet"
point="org.eclipse.equinox.http.registry.servlets">
<servlet alias="/decl/helloworld"
class="com.javaworld.sample.osgi.web.webapp.HelloWorldServlet">
</servlet>
</extension>
<extension id="helloResource"
point="org.eclipse.equinox.http.registry.resources">
<resource alias="/decl/helloworld.html"
base-name="/helloworld.html" />
</extension>
</plugin>
请注意,plugin.xml 具有两个 < extension> 元素。第一个,具有 id 属性,其值为 helloServlet,表示 HelloWorldServlet类将被用于处理 /decl/helloworld 请求。通过将 point 属性的值设置为 org.eclipse.equinox.http.registry.servlets,你可以标示这是 servlet 类。第二个 < extension> 元素,具有指定值为 helloResource 的 id 属性,表示用户请求 /decl/helloworld.html 应返回 helloworld.html 给用户。
现在,使用声明方式重新创建的 HelloWorld OSGi Web应用已经准备好了,并且你可以在 Equinox
OSGi框架中执行你全部的套件。你可以通过 http://localhost/decl/helloworld.html
访问 helloworld.html 以及通过 http://localhost/decl/helloworld
访问
HelloWorld servlet。在下一篇,也是本系列的最后一篇文章中,将介绍如何在Eclipse外部执行OSGi 容器,敬请关注!
相关推荐
OSGI(Open Services Gateway Initiative)是一种模块化系统和Java服务框架,它允许应用程序以模块化的方式构建,每个模块称为一个bundle。在OSGI环境中,你可以动态地安装、启动、更新和卸载这些bundle,而无需重启...
本示例以“基于OSGI的Web开发例子”为主题,主要介绍了如何利用Equinox框架在OSGi环境中进行Web应用的开发,通过一个简单的“Hello World”项目来展示其工作原理。 首先,我们需要理解Equinox。Equinox是Eclipse...
Equinox OSGi是IBM公司开发的一个开源OSGi实现,它是Eclipse项目的一部分,用于创建模块化、可扩展且轻量级的应用程序。OSGi(Open Service Gateway Initiative)是一种Java平台的标准,它允许开发者将应用程序分解...
OSGi(Open Services Gateway initiative)是一个Java平台上的动态模块系统,它允许应用程序和服务动态地被创建、部署和更新。这本书特别关注在企业环境中的OSGi应用,探讨了如何通过模块化和动态性提升企业应用的...
至于压缩包中的"helloWorld"文件,它可能是示例中的一个基本模块,包含了简单的Hello World服务或客户端,用于演示OSGi的基本功能。这个模块可以作为理解OSGi、Maven和IntelliJ IDEA集成的起点。 总之,这个例子为...
在《你好,OSGi》的这篇文章中,作者探讨了如何在OSGi中开发一个简单的Web应用程序,这个应用包含两个资源:helloworld.html(静态HTML文件)和HelloWorldServlet(HttpServlet)。OSGi容器的HttpService允许各个...
在介绍OSGI的基础知识后,接下来通过一个简单的HelloWorld示例来深入理解OSGI的工作原理。 1. **建立第一个Plug-in项目**:使用Eclipse自带的OSGI框架建立第一个插件项目。该插件项目会在控制台输出“HelloWorld”...
描述中的链接指向了博主在iteye上的一个下载资源,这可能是一个详细的教程或实践案例,用于展示如何在OSGi环境中创建和运行一个简单的应用。由于描述是空的,我们无法获取更多具体信息,但通常这样的示例会涵盖如何...
- **创建一个简单的Hello World应用**:展示如何从零开始构建一个RAP应用,包括UI设计、事件处理和部署。 - **构建一个数据管理应用**:通过数据库操作和表格显示,了解如何在RAP中实现数据的CRUD操作。 7. **...
如何让一个应用响应一个特定端口 使用JNDI 使用JNDI 在JNDI中配置数据源(DataSource) 内嵌Jetty服务器 内嵌Jetty教程 内嵌Jetty的HelloWorld教程 内嵌Jetty视频 优化Jetty 如何配置垃圾收集 如何配置以支持高负载 ...
- **Hello World iWidget部署与运行**:从零开始创建并运行一个简单的iWidget实例。 #### 四、iWidget基础知识详解 - **简单iWidget定义**:介绍如何定义一个基本的iWidget。 - **iWidget在网页中的集成**:探讨...
平台的概念对于软件开发者至关重要,它提供了一个基础框架,使得开发人员能够构建可扩展、可定制的应用程序。在Eclipse中,平台不仅仅是一个IDE(集成开发环境),更是一个由众多插件构成的生态系统,支持多语言...
pattern/src/behavior/interpreter //13.11解释器模式 (4)SOA(12个程序包) soa/JAXWSHelloWorldServer.zip //15.JAX-WS服务端——HelloWorld实例 soa/JAXWSHelloWorldClient.zip //15.JAX-WS客户端——Hello...
soa/OSGiHelloWorld.zip.zip //21.OSGi实例——HelloWorld实例 soa/demo.sql //24.SOA服务架构实战——企业信息管理系统数据库脚本 soa/ssh2.zip //24.SOA服务架构实战——企业信息管理系统SSH2代码 soa/...
soa/OSGiHelloWorld.zip.zip //21.OSGi实例——HelloWorld实例 soa/demo.sql //24.SOA服务架构实战——企业信息管理系统数据库脚本 soa/ssh2.zip //24.SOA服务架构实战——企业信息管理系统SSH2代码 soa/...
pattern/src/behavior/interpreter //13.11解释器模式 (4)SOA(12个程序包) soa/JAXWSHelloWorldServer.zip //15.JAX-WS服务端——HelloWorld实例 soa/JAXWSHelloWorldClient.zip //15.JAX-WS客户端——Hello...