导航

OSGi系列 - 开发服务端Web应用之一:Servlet实现

Posted on 2012-05-17 11:42  eastson  阅读(3463)  评论(0编辑  收藏  举报

在OSGi框架下如何开发Web应用?这是个问题。OSGi框架下的Web应用运行方式可以归纳为两种:第一种,将Web容器作为一个Bundle,然后运行在OSGi框架中。第二种,将OSGi框架置于Web容器中。本系列文章以第一种运行方式为主,在系列的最后会适当的对第二种运行方式做些介绍。

 

第一步:打开Eclipse,新建Bundle项目HelloWorldBundle(使用Elicpse建立Bundle项目的详细过程可以参考 OSGi系列 - 用Eclipse开发Bundle)。HelloWorldBundle项目的目录结构如下图:

 

第二步:打开MANIFEST.MF文件,切换到Dependencies标签页,在Required Plug-ins加入两个依赖插件:javax.servletorg.eclipse.osgi.services。javax.servlet提供了我们开发Servlet时必需的Servlet API,org.eclipse.osgi.services提供在Activator注册我们编写的Servlet时需要用到的HTTP服务。

保存MANIFEST.MF,完整的ANIFEST.MF内容如下:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloWorldBundle
Bundle-SymbolicName: HelloWorldBundle
Bundle-Version: 1.0.0
Bundle-Activator: helloworldbundle.Activator
Import-Package: org.osgi.framework;version="1.3.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: javax.servlet;bundle-version="2.5.0",
 org.eclipse.osgi.services;bundle-version="3.3.0"

 

第三步:新建HelloServlet .java,作为我们的Servlet演示。HelloServlet .java的内容如下:

package helloworldbundle;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.osgi.framework.BundleContext;

public class HelloServlet extends HttpServlet 
{
    private static final long serialVersionUID = 1L;
    
    @SuppressWarnings("unused")
    private BundleContext context;
    
    public HelloServlet(BundleContext context)
    {
        this.context = context;
    }

    public void doGet(HttpServletRequest request,  HttpServletResponse response) throws IOException
    {
         HttpSession session = request.getSession();
         
         int counter;
         if (null != session.getAttribute("counter")) {
             counter = (Integer) session.getAttribute("counter") + 1;
         } else {
             counter = 1;
         }
         session.setAttribute("counter", counter);
         
         response.setCharacterEncoding("GBK"); 
         response.setContentType("text/html");
         
         PrintWriter out = response.getWriter(); 
         out.println("<html>"); 
         out.println("<body>"); 
         out.println("<head>"); 
         out.println("<title>Hello World</title>"); 
         out.println("</head>"); 
         out.println("<body>"); 
         out.println("Now time: " + (new java.util.Date()) + ", Counter: " + counter); 
         out.println("</body>"); 
         out.println("</html>"); 
         out.flush(); 
         out.close(); 
    }
}

 

 

第四步:实现Activator.java,管理HelloWorldBundle的生命周期。在Activator的启动和停止方法里面,我们相应的增加和删除了一个服务监听器,用来监听Http服务的注册和卸载。当HTTP服务被注册时,同时将HelloServlet注册到HTTP服务;当HTTP服务被卸载时,同时也将HelloServlet从HTTP服务上卸载掉。Activator.java的内容如下:

package helloworldbundle;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;

public class Activator implements BundleActivator, ServiceListener 
{
    private BundleContext ctx;
    private ServiceReference<HttpService> ref;
    
    public void start(BundleContext context) throws Exception 
    {
        ctx = context;
        context.addServiceListener(this, "(objectClass=" + HttpService.class.getName() + ")");
    }

    public void stop(BundleContext context) throws Exception 
    {
        context.removeServiceListener(this);
    }

    public void serviceChanged(ServiceEvent event) 
    {
        switch (event.getType()){
            case ServiceEvent.REGISTERED:
                registerServlet();
                break;
    
            case ServiceEvent.UNREGISTERING:
                unregisterServlet();
                break;
        }
    }
    
    private void registerServlet()
    {
        if (ref == null) {
            ref = ctx.getServiceReference(HttpService.class);
            
            if (ref != null) {
                try {
                    HttpService http = ctx.getService(ref);
                    
                    http.registerServlet("/demo/hello", new HelloServlet(ctx), null, null);
                    System.out.println("/demo/hello已经被注册");
                    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } 
        }
    }
    
    private void unregisterServlet() 
    {
        if (ref != null) {
            try {
                HttpService http = ctx.getService(ref);
                
                http.unregister("/demo/hello");
                System.out.println("/demo/hello已经被卸载");
                
                ref = null;
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    }

}

 

第五步:从Elicpse菜单上选择Run >> Run Configurations...,在弹出的Run Configurations对话框左侧列表中找到OSGi Framework,点击New按钮:

在右侧Bundles列表中,选择Workspace下的HelloWordBundle项目,然后在Target Platform下选择一下项目:

  • javax.servlet
  • org.eclipse.osgi.services
  • org.eclipse.equinox.http.servlet
  • org.eclipse.equinox.http.jetty
  • org.mortbay.jetty.server
  • org.mortbay.jetty.util

最后点击对话框右下角的Run按钮,如果一切正常,就会出现我们熟悉的osgi>提示符:

 

第六步:打开浏览器,输入网址http://localhost/demo/hello,如果出现下面的画面,那么,恭喜你,成功了。

 

撰写本文章,特别需要感谢《OSGI实战》和《使用 Equinox 框架进行 OSGi 环境下的 Web 开发》两篇文章对我的指点,谢谢!