利用OSGi DS实现可配置Web应用程序初探

简介:

Eclipse的插件体系结构让我们可以灵活定义插件,组装成可插拔的软件系统,OSGi的Declarative Services(DS)有着和Eclipse扩展点类似的思想(见很详细的一篇对比文章),很自然的想到,如果把DS应用在Web应用程序上,我们将能够通过定义自己的“扩展点”,打造SOA的Web应用程序。题目中“可配置”是指,根据用户需求,提供给客户不同的包即可形成针对该客户定制的产品/解决方案。

现在来试试怎样用DS实现动态配置一个Web应用程序界面里菜单,使用的OSGi实现还是Equinox。Eclipse里菜单项是通过实现actionSets、editorActions等等扩展点添加的,在OSGi里没有这些“扩展点”,没关系,我们可以自己定义。

一、用一个Bundle定义Java接口文件,和Eclipse扩展点的功能类似,这些接口可以作为服务的接入点。例子里这个Bundle的ID是net.bjzhanghao.osgi.services,接口类是IMenuContributor,内容很简单如下所示:

public   interface  IMenuContributor {
    
    
public  List < MenuItem >  getItems();
    
}

上面用到的MenuItem是自己定义的一个简单的数据结构,包含name和url两个String类型的成员变量和相应的getter/setter方法,这里就不展示了。

二、用0..n个Bundle实现上面定义的接口(暂时称之为Contributor),并声明为服务。例子里有两个这样的Bundle,ID分别是net.bjzhanghao.osgi.menu.contributor和net.bjzhanghao.osgi.menu.contributor2,实现类都是MyMenuContributor,前者提供了Menu1..3,后者提供了Menu4..5;以下是服务的声明,即项目里OSGI-INF/component.xml文件的内容:

<? xml version="1.0" encoding="UTF-8" ?>
< component  name ="services" >
    
< implementation 
        
class ="net.bjzhanghao.osgi.menu.contributor.MyMenuContributor" />  
    
< service >
        
< provide  interface ="net.bjzhanghao.osgi.services.IMenuContributor" />
    
</ service >
</ component >

MyMenuContributor实现IMenuContributor,你可以任意实现它,例子里是让它提供三个菜单项:

public   class  MyMenuContributor  implements  IMenuContributor {

    
public  List < MenuItem >  getItems() {
        List
< MenuItem >  list  =   new  ArrayList < MenuItem > ();
        list.add(
new  MenuItem( " Menu1 " null ));
        list.add(
new  MenuItem( " Menu2 " null ));
        list.add(
new  MenuItem( " Menu3 " null ));
        
return  list;
    }

}

三、现在SOA的一半工作也就是注册服务的部分完成了,剩下要做的是另一半,消费这些服务。首先在web应用程序Bundle里,创建一个Helper类收集这些服务,这个Helper类的功能相当于一个Registry。例子里这个Bundle的ID是net.bjzhanghao.osgi.example,Helper类是MenuHelper;以下是对MenuHelper的配置,即项目里OSGI-INF/component.xml文件的内容,这样OSGi在启动Bundle时会把实现IMenuContributor的服务通过addMenuContributor方法注册到MenuHelper里,注意cardinality的值要为"0..n",policy的值要为"dynamic":

<? xml version="1.0" encoding="UTF-8" ?>
< component  name ="menuHelper" >
    
< implementation     
        
class ="net.bjzhanghao.osgi.example.MenuHelper" />    
    
< reference  name ="menuHelper"
        interface
="net.bjzhanghao.osgi.services.IMenuContributor"
        cardinality
="0..n"
        policy
="dynamic"
        bind
="addMenuContributor"
        unbind
="removeMenuContributor"
    
/>
</ component >

四、在JSP/Servlet里,利用上面的Helper类构造界面(或业务逻辑)。因为我们定义的接口是关于菜单的,所以例子应用的菜单会根据Bundle配置(启动/停止)变化。例子里是在ExampleServlet里实现的,代码很简单如下所示:

protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)  throws  ServletException, IOException {
    resp.setContentType(
" text/html " );
    resp.getWriter().write(
" Hello<br/> " );
    resp.getWriter().write(
" <ul> " );
    
for  (IMenuContributor menuContributor : MenuHelper.getInstance().getMenuContributors()) {
        
for  (MenuItem mItem : menuContributor.getItems()) {
            resp.getWriter().write(
" <li><a href=\ ""  + mItem.getUrl() +  " \ " > "   +  mItem.getName()  +   " </a></li> " );
        }
    }
    resp.getWriter().write(
" </ul> " );
}

五、执行方式:

1、在Eclipse里导入代码包里所有项目,启动上述所有项目及其依赖的项目(Add Required Bundles),见下图:


2、在浏览器里输入地址http://localhost/exampleServlet,应该可以看到五个菜单项,见下图(这个简单的例子里没有考虑顺序问题,所以Menu4..5可能出现在前面,使用类似Eclipse里为Menu预留位置的方式可以解决):


3、回到Eclipse,在Console里输入ss查看当前的Bundle,应该可以看到类似下图的内容:


4、在Console里输入stop 35(35是Contributor的Bundle序号),Console会提示“Calling removeMenuContributor”,然后到浏览器里刷新页面,应该看到菜单项只剩下Menu4..5。


代码下载

本文转自博客园八进制的博客,原文链接:利用OSGi DS实现可配置Web应用程序初探,如需转载请自行联系原博主。

相关文章
|
1天前
|
Go
golang学习3,golang 项目中配置gin的web框架
golang学习3,golang 项目中配置gin的web框架
|
2天前
|
XML 开发框架 .NET
C#/ASP.NET应用程序配置文件app.config/web.config的增、删、改操作
C#/ASP.NET应用程序配置文件app.config/web.config的增、删、改操作
|
6天前
|
开发框架 JSON .NET
.Net4.0 Web.config 配置实践
.Net4.0 Web.config 配置实践
|
14天前
|
监控 测试技术 API
Python Web应用程序构建
【4月更文挑战第11天】Python Web开发涉及多种框架,如Django、Flask和FastAPI,选择合适框架是成功的关键。示例展示了使用Flask创建简单Web应用,以及如何使用ORM(如SQLAlchemy)管理数据库。
31 4
|
24天前
|
SQL 安全 Go
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
在Python Web开发中,确保应用安全至关重要,主要防范SQL注入、XSS和CSRF攻击。措施包括:使用参数化查询或ORM防止SQL注入;过滤与转义用户输入抵御XSS;添加CSRF令牌抵挡CSRF;启用HTTPS保障数据传输安全;实现强身份验证和授权系统;智能处理错误信息;定期更新及审计以修复漏洞;严格输入验证;并培训开发者提升安全意识。持续关注和改进是保证安全的关键。
20 0
|
2月前
|
前端开发 JavaScript 数据管理
描述一个使用Python开发Web应用程序的实际项目经验,包括所使用的框架和技术栈。
使用Flask开发Web应用,结合SQLite、Flask-SQLAlchemy进行数据管理,HTML/CSS/JS(Bootstrap和jQuery)构建前端。通过Flask路由处理用户请求,模块化代码提高可维护性。unittest进行测试,开发阶段用内置服务器,生产环境可选WSGI服务器或容器化部署。实现了用户注册登录和数据管理功能,展示Python Web开发的灵活性和效率。
16 4
|
2月前
|
SQL 运维 监控
什么是Web应用程序防火墙,WAF与其他网络安全工具差异在哪?
总之,WAF是一种专门用于保护Web应用程序的网络安全工具,与其他网络安全工具在焦点、层级、检测方式、部署位置和针对性等方面存在差异,以确保Web应用程序的安全运行。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
124 0
|
2月前
|
数据库
最全三大框架整合(使用映射)——struts.xml和web.xml配置
最全三大框架整合(使用映射)——数据库资源文件jdbc.properties
10 0
|
2月前
|
缓存 监控 前端开发
如何优化 Python WEB 应用程序的性能?
【2月更文挑战第27天】【2月更文挑战第93篇】如何优化 Python WEB 应用程序的性能?
|
2月前
|
SQL 安全 测试技术
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
18 0