- 浏览: 60661 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
hheuii:
咱们犯的错误一样,看报错真难找
Ibatis报错:Error parsing XPath '/sqlMap/insert'. Cause: java.util.NoSuchElementEx -
shencaifeixia:
不错,正迷茫着呢
Opengles之glRotatef()函数解析 -
wh176781788:
写的不错
OSGi动态化深入分析 -
lattimore:
这里说明的很详细:
http://www.developer. ...
Android UI背景图片之NinePatch图片
转载自http://www.ibm.com/developerworks/cn/web/1007_shaobing_flexosgi/index.html?ca=drs-
这篇文章的项目会有两个问题:
1. 报错velocity......的异常,因为缺少了velocity-tools-1.3.jar 包。
2. 如果无法上网时解析struts.xml会报错,请修改src下的struts.xml的dtd文件的url 为
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"file:/D:/saber/workspace/OSGISSH/dtd/struts-2.0.dtd">
同时如果导入struts2-osgi-admin-bundle-2.2.3.jar ,也要修改这个包下的struts.xml的头!
Open Service Gateway Initiative(OSGi) 是一个针对 Java 动态模块开发的规范。基于中间件的 OSGi 技术提供了一个面向服务,基于组件的开发环境,并提供标准化的方式来管理整个软件生命周期。OSGi 为那些需要长时间运行,动态更新并且对运行环境的影响尽可能小的系统提供了很好的支持。基于 OSGi 开发的系统具有复杂度低、可重用、动态部署、可持续运行、开发简单等特点。
OSGi 技术结合了上述特点的各方面来定义一个动态服务部署框架,可以进行远程管理。OSGi 技术起初只是关注于嵌入式领域,诸如机顶盒、服务网关、手机等应用环境。但是它完美地适用在任一模块化、面向组件、面向服务的项目。Eclipse V3.0 以后采用 OSGi 作为其模块化和动态化平台,设计了 Equinox 内核,使用 OSGi 技术帮助其进行类载入,大大提升了 Eclipse 的启动速度。在应用服务器上,WebSphere,Weblogic,JBOSS 等著名的服务器都支持或使用了 OSGi 技术。
Felix 是一个 Apache 旗下 OSGi 实现的开源框架,它的最终的目标是提供一个完全兼容的 OSGi 框架和标准服务的实现。Felix 当前实现了 OSGi 规范 4 的大部分内容,目前 Felix 提供的 OSGi 框架功能是非常稳定的。
采用 Spring DM 和 Jetty 等 Web 容器开发基于 OSGi 的 Web 应用的方法已经在很多书本或技术文章上提及。但是这种开发方法与传统的 Web 开发差别较大,开发人员很难转换到这种开发模式上,并且它的稳定性也没有得到充分的验证。
很多 Web 开发都采用 Struts 作为其控制层,很幸运的是,最新发布的 Struts2.1.8.1 中,加入了对 Felix OSGi 的支持,能够在传统的 Web 开发中集成 OSGi 的模块管理平台,而且开发方法没有太大的改变,开发后的应用程序仍像原先一样可以方便的部署在 Tomcat,JBoss 等容器上。
本文将通过下面的示例,详细讲述如何使用 Felix 和 Struts 开发 Web 应用。
下面讲解的示例是一个获取时间信息并在 Web 浏览器中显示的简单示例,该示例主要介绍了怎样使用 Felix 和 Struts 结合起来开发 Web 应用。该示例中有两个获取时间信息的 bundle,这两个 bundle 实现同一个接口服务,但是有不同的实现,这两个 bundle 可以在应用中动态部署。通过该示例,可以体现出基于 OSGi 开发的项目具有良好的模块化以及 OSGi 的 bundle 动态部署的能力,从而说明了 OSGi 适用于开发持续运行且需要动态更新的系统。
在这个示例中,一共包括五个工程,一个 Web Application 工程和四个 OSGi bundle 工程。Web Application 工程是用于 Web 部署。四个 OSGi bundle 中,包括一个 Web bundle,用于 Web 交互;一个 time service bundle,包含一个获取时间信息的接口服务;一个 local time service bundle,实现接口服务,用于获取本地时间信息;一个 utc time service bundle,用于获取世界标准时间(Universal Time Coordinated,UTC)信息。
本示例的结构原理如图 1 所示。在 Web Container 中注册了 Struts OSGi 的监听器,该监听器会去启动或停止 Apache Felix Host,Apache Felix Host 是 Struts OSGi Plugin 和 Felix Framework 的连接点。Felix Host 会去创建和初始化 Felix Framework,Felix Framework 负责管理系统中的其余的所有 bundle,Struts OSGi Plugin 会监听 bundle 的变化,如果发生变化的 bundle 是一个 Struts bundle, 则会去加载 Struts 的配置。
本文示例使用的 Web 开发环境包括如下组件,部分框架可以 参考资料中下载。
- Eclipse 3.5 for Java EE Developers
- Sun JDK 1.6.0
- Tomcat 6.0.24
- Struts 2.1.8.1 (Essential Dependencies Only)
- spring-osgi-1.1.2-with-dependencies (Only Need when adding Spring Support)
Web Application 工程的创建方式与通常的 Web 工程类似,但是需要加入 Felix 的支持和 Struts2 OSGi Plugin. Felix 是 OSGi 的平台,用于管理整个系统中的所有的 bundle,而 Struts2 OSGi Plugin 是 Struts2 和 OSGi 连接的桥梁,通过 Struts2 OSGi Plugin 将 Felix 融入到 Struts2 框架中。另外,还需要加入 Struts2 OSGi Admin bundle,这个 bundle 向管理人员提供基于 Web 的管理 OSGi 平台中的 bundle 的操作入口。同时在 web.xml 中需要加入 Struts OSGi 监听器,这样 OSGi 平台中的 bundle 发生变化时,会触发该监听器去做一些与 Struts 相关测操作,例如增加 Action 或使 Action 失效。
web.xml 中过滤器和监听器部分的配置内容如清单 1:
<filter> <filter-name>struts2-prepare</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class> </filter> <filter> <filter-name>struts2-execute</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2-prepare</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts2-execute</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.apache.struts2.osgi.StrutsOsgiListener</listener-class> </listener> <listener> <listener-class>org.apache.struts2.dispatcher.ng.listener.StrutsListener </listener-class> </listener> |
Web Application 工程的目录结构如图 2 所示:
将 Web Application 部署到 Tomcat 上并启动 Tomcat,然后在浏览器中输入 http://localhost:8080/webapp/osgi/admin/bundles.action, (webapp 是项目部署到 Tomcat 中的名字 ) 如果看到了类似于 图 5的 bundles 列表,说明 OSGi 环境配置成功。
消息接口服务 bundle 是提供消息服务的接口,该接口将被 Web bundle 所使用,其他 bundle 可以不同的形式实现该接口。在这里利用 eclipse 新建插件工程的功能来创建 OSGi bundle。需要特别设置 an OSGI framework 为 standard 方式,这种方式允许部署项目到标准的 OSGI 容器中。新建 OSGi 工程的向导如图 3 所示。
在该项目中开发一个用于获取时间信息的接口,通过该接口可以获取字符串形式的时间信息。
package com.example.time.service; public interface TimeService{ public String getTime(); } |
需要将该 bundle
中的服务包的类和接口就暴露给了其他的 bundle
,其他的 bundle
可以通过 import
这个包来使用其中的类和接口。
获取本地时间消息服务 bundle 实现了时间消息接口服务。在该 bundle 种返回的时间消息是当前时区的时间信息。因为用到了接口服务包,所以需要在 Import-Package 中加入接口服务包。
package com.example.time.local.service; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import com.example.time.service.TimeService; public class LocalTimeService implements TimeService{ @Override public String getTime(){ Calendar calendar = Calendar.getInstance(); Date date = calendar.getTime(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return "The local time:" + formatter.format(date); } } |
OSGi bundle 中的服务要能够被其他 bundle 使用,使用将服务发布出来。在该 bundle 的 Activator 的 start() 方法中注册该服务,可以发布这个服务。当这个 bundle 启动时,将获取本地时间发布为一个服务。服务发布的代码如清单 4 所示。
public void start(BundleContext context) throws Exception{ context.registerService(TimeService.class.getName(), new LocalTimeService(), null); } |
获取 UTC 时间消息实现服务同样实现了时间消息接口服务,该 bundle 主要是用于和上一个 bundle 即获取本地时间消息服务进行动态的替换,用于表现 OSGi 的动态部署的能力。
public class UTCTimeService implements TimeService { @Override public String getTime() { Calendar calendar = Calendar.getInstance(); int zoneOffset = calendar.get(Calendar.ZONE_OFFSET); int dstOffset = calendar.get(Calendar.DST_OFFSET); calendar.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset)); Date date = calendar.getTime(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm s"); return "The UTC time:" + formatter.format(date); } } |
Web bundle 是系统 Web 交互的入口。在该 bundle 中需要使用时间消息接口服务 bundle 中的接口,所有需要在 MANIFEST.MF 的 Import-Package 加入时间消息接口服务包,另外,为了能够识别出该 bundle 是一个 Struts bundle, 需要将该 bundle 设置为可被 Struts2 支持 , 即在 MANIFEST.MF 中加入 Struts2-Enabled: true, 这样该 bundle 中的 struts.xml 就会被加载。最终的 MANIFEST.MF 的配置如清单 6。
清单 6. Web Bundle 的 MANIFEST.MF 配置
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: com-example-time-web Bundle-SymbolicName: com.example.time.web Bundle-Version: 1.0.0.qualifier Bundle-Vendor: keki Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Struts2-Enabled: true Import-Package: com.example.time.service, com.opensymphony.xwork2, org.apache.struts2.osgi.interceptor, org.osgi.framework;version="1.3.0" |
为了实现用户交互,还需要创建一个获取时间消息响应的 action。该 Action 的 execute() 方法代码如清单 7 所示。
public String execute(){ ServiceReference ref = bundleContext.getServiceReference( TimeService.class.getName()); TimeService timeService = (TimeService) bundleContext.getService(ref); timeMessage = timeService.getTime(); return SUCCESS; } |
这个 Web bundle 中独立的建立一个 struts.xml,这个 struts.xml 将会为单独加载,需要注意的是 Struts 的 pacakge 继承 osgi-default 这个包,osgi-default 已在 struts2-osgi-plugin 这个 jar 包里面定义。
清单 8. Web Bundle struts.xml 的 action 定义
<struts> <package name="time-example" namespace="/time" extends="osgi-default"> <action name="time" class="com.example.time.web.action.TimeAction"> <result type="freemarker">time.ftl</result> </action> </package> </struts> |
将开发好的四个 bundle 导出成 plugin 的包,并将它们放在 Web App 工程中 ,bundles 的目录结构如图 4 所示。
图 4. Web Application 中的 bundles 目录结构
启动 Tomcat,在浏览器地址栏输入 http://localhost:8080/webapp/osgi/admin/bundles.do, 可以看到所系统中所有的 bundle 的列表。
在浏览器地址栏输入 http://localhost:8080/webapp/time/time.do,可以获得时间信息,此时的时间信息为本地时间信息,当前 TimeService 这个服务有 local time service 和 UTC time service 两个实现,调用的是 local time service 这个实现。
此时,在浏览器地址栏输入 http://localhost:8080/webapp/osgi/admin/shell.do,然后输入命令 stop 1, 将 Local time service 这个 bundle 停止掉,输入命令 ps, 可以看到 local time service 这个 bundle 的 state 已经变为 Resolved.
在浏览器地址栏再次输入 http://localhost:8080/webapp/time/time.do 得到的结果如图 7 所示。
通过上面的演示,我们可以看到 OSGi bundle 的动态部署能力。
通过 Felix 可以方便的管理项目中的 bundle,并且实现 bundle 的热部署,即插即用,即删即无的特性,特别适用于可持续运行的系统。
输入命令 install <bundle-url>,然后输入 start <bundle-id> 即可。如 $install file:/k:/plugins/com.example.time.local_1.0.0.qualifier.jar , $start 7
输入命令 update <bundle-id> <bundle-url> 即可。如
$ update 1 file:/k:/plugins/com.example.time.local_1.0.0.qualifier.jar
输入命令 start <bundle-id> 启动 bundle;输入命令 stop <bundle-id> 停止 bundle。如
$ start 2 , $ stop 1
若 bundle 处于 Installed 或 Resolve 状态,则直接输入命令 uninstall <bundle-id>。若 bundle 处于 Actived 状态,则先输入命令 stop <bundle-id> 停止 bundle, 再输入命令 uninstall <bundle-id>。如 $ uninstall 1
在上面的示例中,bundle 中最大的启动级别只能为 3。如果在 bundles 下面增加一个目录 4,即 bundles/4,则目录 4 中的 bundle 是无法启动的,而在很多时候,特别是在大型的项目中,最大启动级别为 3 是不能满足要求,此时可以 web.xml 中添加启动级别的参数。如下面把最大启动级别设置为 5。
<context-param> <param-name>struts.osgi.runLevel</param-name> <param-value>5</param-value> </context-param> |
解决 Bundle 中的 struts.xml 的 Struts Configuration DTD 无法定位的问题
Struts.xml 的头部有 Struts Configuration DTD 的引用定义,一般 DTD 文档的 URL 为 http://struts.apache.org/dtds/XXX.dtd ,示例如下所示:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> |
如果无法连接上 http://struts.apache.org/,那么在加载 Struts 的 bundle 时也将会出错,因为 bundle 与 Web Application 的 lib 的加载路径不一致,无法从 Web Application 的 lib 下面找到 XXX.dtd 文件。此时可以通过修改 dtd 文件的 URL 来解决,可以改成一个本地文件系统的 URI,如 file:/c:/webapp/dtds/struts-2.0.dtd,也可以改为本地的 Web 服务器或一个可以连接上的服务器的 URL,如 http://localhost/dtds/struts-2.0.dtd。
Spring DM 使得 Spring 和 OSGi 成为可能,在本文的开发环境中,也可以加入 Spring DM 来管理系统中的对象。首先加入 Spring DM 必要的 jar 包,如
com.springsource.org.aopalliance-1.0.0.jar, com.springsource.org.apache.commons.logging-1.1.1.jar, spring-aop-2.5.5.jar, spring-beans-2.5.5.jar, spring-context-support-2.5.5.jar, spring-core-2.5.5.jar, spring-osgi-core-1.1.2.jar, spring-osgi-extender-1.1.2.jar, spring-osgi-is-1.1.2.jar, spring-osgi-web-1.1.2.jar, spring-osgi-web-extender-1.1.2.jar, spring-web-2.5.5.jar |
然后需要在 Web Application 的 struts.xml 中加入对象工厂的配置,配置如下:
<constant name="struts.objectFactory" value="osgi" /> <constant name="struts.objectFactory.delegate" value="springOsgi" /> |
在 Web Application 的 web.xml 加入 Spring 的监听器 , 配置如下:
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <context-param> <param-name>contextClass</param-name> <param-value> org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext </param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>osgibundle:/META-INF/spring/*.xml,/spring/*.xml </param-value> </context-param> <context-param> <param-name>parentContextKey</param-name> <param-value>parent-context-bean</param-value> </context-param> |
在 OSGi bundle 中,如果需要用 Spring 来管理对象,则把 Spring 对象的配置文件放在 /META-INF/spring/ 目录下面,并以 xml 为扩展名即可。Spring 对象配置文件的写法在很多 Spring DM 的书籍或文章中都有讲解,这里不再重复。最后需要在 MANIFEST.MF 中加入如下声明用来配置 Spring 上下文和对象创建机制,create-asynchronously 的值为 true 表示可以允许异步创建对象。
Spring-Context: *;create-asynchronously:=true |
本文首先对 OSGi 和 Felix 进行了简要的介绍,然后通过一个示例详细介绍了使用 Felix 和 Struts 开发 Web 应用,演示了 OSGi 的动态部署特性。随后,讲解了 OSGi bundles 管理常用的命令操作,以及在开发过程中的几个常见的问题的解决方法。
<!-- CMA ID: 500011 --><!-- Site ID: 10 --><!-- XSLT stylesheet used to transform this file: dw-article-6.0-beta.xsl -->
学习
- 查看 OSGi 联盟和技术规范:了解更多和 OSGi 相关的内容和动向。
- 查看 Apache Felix 官方网站:在这里您可以下载到最新版本的 Felix 库,并找到相关的开发文档。
- 查看 Equinox 项目官方网站:您可以从这里了解到 Equinox 项目的一些详情,例如实现方法、文档等。
- 下载 Struts2 2.1.8.1,获得最新的 Structs 2 的代码包。
- 查看 Spring DM,获得最新的 Spring Dynamic Modules for OSGi 代码包。
-
developerWorks Web development 专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。
-
developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。
-
developerWorks Web 2.0 资源中心,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过 Web 2.0 新手入门栏目,迅速了解 Web 2.0 的相关概念。
讨论
相关推荐
在开发Web应用的过程中,Felix和Struts2是两种重要的技术。Felix是Apache软件基金会提供的一个开源实现,它是基于OSGi(Open Service Gateway Initiative)规范的Java框架,主要用于管理和运行模块化的Java应用程序...
本文深入浅出地解释了如何结合Felix和Struts2构建基于OSGi的Web应用,通过一个具体的时间服务示例展示了OSGi的动态部署和模块化特性。这种开发方式使得Web应用的维护和扩展更为灵活,适应性强,尤其适合需要长期运行...
标题 "Felix+Struts2做的web示例" 暗示了这是一个使用Apache Felix作为OSGi容器,并结合Struts2框架构建的Web应用程序。Apache Felix是一个开源的OSGi实现,它允许开发者将应用程序分解为模块化组件,使得代码更易于...
本项目结合了Struts2和Felix1.4,构建了一个基于OSGI的Web基础设施,提供了灵活和可扩展的框架来开发Web应用。 在OSGI环境中,应用被分解为小型的、独立的模块,称为bundle。每个bundle包含一组相关的类和资源,...
总的来说,"struts2+Hibernate+felix1.4.0 integrated"是一个将现代Web开发技术与模块化应用管理相结合的项目,它展示了如何在Java环境中利用这些工具构建高效、可扩展的Web应用。这样的集成不仅提高了开发效率,也...
Struts2是一个流行的Java Web应用程序框架,它基于MVC(Model-View-Controller)设计模式,为开发者提供了构建可维护性和可扩展性良好的Web应用的工具。此压缩包中的文件包含了Struts2的核心组件、插件以及一些依赖...
MyEclipse是基于Eclipse的一款强大的集成开发环境(IDE),特别适合Java和Web应用的开发。它集成了代码编辑、调试、构建、部署等功能,并且支持多种框架,如Struts、Spring和Hibernate。MyEclipse的使用可以极大地...
4. `asm-commons-3.3.jar`: ASM是一个字节码操作库,常用于动态代理和代码生成,XWork和Struts 2使用它来进行运行时类的修改和增强。 5. `spring-beans-3.0.5.RELEASE.jar`: 这是Spring框架的一部分,用于管理Bean...
在开发Java Web应用程序时,Struts2和Spring的集成是一个常见的选择,它们分别负责MVC框架和依赖注入。然而,在采用共享JAR包部署这样的集成项目时,可能会遇到一些问题。这篇博客文章“采用共享jar包部署struts2+...
Struts2是一个流行的Java web应用程序框架,用于构建和维护可扩展、高效且易于管理的企业级应用。版本2.3.15是该框架的一个特定发行版,它在设计上注重灵活性和可配置性,同时也提供了丰富的功能集。在这个特定的...
Struts2则是一个流行的Java MVC框架,它简化了创建Web应用的过程,提供了丰富的插件和拦截器机制,以及强大的Action类和结果映射,使得业务逻辑和视图分离。 集成Spring DM与Struts2的目的是为了充分利用两者的优势...
在Java Web项目开发中,我们通常涉及到一系列的技术和概念,这些技术构成了Web应用程序的基础。"Java Web项目开发案例"提供了一个实践性的学习平台,通过实际的项目案例来深入理解这些概念和技术。以下是一些关键的...
Struts2是一个基于MVC(Model-View-Controller)设计模式的开源Java Web应用框架,用于简化开发过程,提供强大的表单验证和页面导航功能。`struts2-embeddedjsp-plugin-2.1.8.jar` 是Struts2的内嵌JSP插件,用于处理...
6. **Struts1 and Struts2**: Struts是两个流行的MVC(Model-View-Controller)框架,用于构建Web应用。Struts1的JAR包包括`struts.jar`和`struts-config_1_3.dtd`等,而Struts2则需要`struts2-core.jar`,以及相关...
**SSH框架介绍** SSH是Java Web开发中的一个经典组合,由Struts2、Spring和...这个校园微博系统虽然功能简单,但对于初学者来说,是一个很好的实践项目,能帮助他们掌握SSH框架的基本使用和Web应用的开发流程。
理解它们的工作原理和区别,以及如何在Java Web应用中合理使用,是开发中的重要环节。 7. **Spring框架**:Spring不仅提供依赖注入(DI)和面向切面编程(AOP),还包含了Spring MVC和Spring JDBC等模块,大大简化...
总之,"学生成绩管理系统(SSH+MYSQL)"项目是一个典型的Java Web应用实例,通过这个项目,不仅可以学习到如何使用SSH框架搭建后台系统,还能深入理解MySQL数据库的运用,以及整个Web应用的开发流程。对于IT从业者而言...
在IT领域,文件上传下载是Web应用程序中常见的功能,它涉及到服务器与客户端之间的数据交互。以下将详细讲解标题和描述中涉及的知识点: 1. **Servlet文件上传**:Servlet是Java Web开发中的一个核心组件,可以处理...
2. **Servlet与JSP**:Servlet作为Java Web应用的核心组件,处理HTTP请求,而JSP则用于视图层的展示,将业务逻辑和展示逻辑分离,提高代码可读性和复用性。 3. **Java持久层技术**:Hibernate、MyBatis等框架用于...
ExtJS是一个流行的JavaScript库,它允许开发者构建功能丰富的、用户友好的Web应用程序。在本项目中,dogdisk是一个基于ExtJS 2.2实现的网络存储解决方案,它提供了文件的上传和下载功能,为用户提供了一种在线管理其...