在OSGI容器Equinox中嵌入HttpServer

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在OSGI容器Equinox中嵌入HttpServer相关的知识,希望对你有一定的参考价值。

原文地址:https://liugang594.iteye.com/blog/1328050

简单介绍一下如何在一个osgi的bundle中内嵌使用http服务

一、基础

首先看看在OSGI中怎么启动内嵌的jetty容器。看下图:

技术图片

 

其实简单的只选中"org.eclipse.osgi"和"org.eclipse.equinox.http.jetty",然后点击"Add Required Bundles"即可。

默认的Jetty监听的端口为80,可又通过指定运行参数 org.osgi.service.http.port 来修改围住端口,例如要想使用8080端口,可又切换到 "Arguments"页:

技术图片

 

 完成配置又后,点运行即可:

技术图片

 

 如果得到又上结果,说明运行成功,可以访问一下启动的jetty了:

 技术图片

 

 

二、添加页面

上面介绍了怎么在Eclipse的OSGI容器里启动Jetty服务,不过从结果看来,这个jetty里还没有什么内容。这一节我们就要加一点内容。

 

首先,先创建一个简单的osgi的bundle,过程如下:

  1. New --> Other --> Plug-in Project, 点 “Next”
  2. 填写“Project name”;
  3. "Target Platform"一栏,选择“an OSGI framework" --> "standard", 点 "Next", "Next"

 技术图片

  1. 不选任何模板,直接Finish

OK,一个基本OSGI的bundle project就创建完成。要结合使用http服务,需要添加以下依赖包:

  • javax.servlet
  • javax.servlet.http
  • org.osgi.service.http

 技术图片

 

 

OK,配置部分就已经完成,下面就开始填写内容。

三、背景知识

Eclipse内嵌有一个HttpService的实现,它位于包"org.osgi.service.http"下,一旦这个service所在的osgi bundle启动了,就会有一个内嵌的http容器被启动,这个service就会被注册,默认地址是http://localhost,端口为80,可以通过指定参数“org.osgi.service.http.port”参数在运行的时候修改默认端口(参见上上节)。(注:不应该试图自己去启动他那HttpService服务,那样可能达不到目的;另外应避免启动多个HttpService服务,又节省资源)

 

要想提供我们自己定义的http服务,就需要将我们的服务(servlet或者是其他html页面)注册到这个HttpService中去,这里主要是用到HttpService的两个注册方法:

  • registerResources(String alias, String name, HttpContext context) 

          用来注册诸如表态页面等等

  • registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext context)

          用来注册servlet类

所以要想提供我自己的webservice实现,我们就需要:

 

  1. 取得httpService对象
  2. 提供Servlet和Web Page的实现
  3. 将Servlet和Web Page注册到HttpService服务中
  4. 访问

四、实现

我这里提供一个很简单的例子:一个页面,用户可又输入名字,然后点提交,将输入的信息提交到后台的servlet;servlet得到提交的名字,如果不为空,就将它打印出来,否则就提示用户需要输入一个名字。

 

1、准备页面

提交页面的内容如下:

 

<html>  
<title>测试OSGI和HTTP</title>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
<body>  
<form action="print" method="get">  
请输入名字:  
  <input type="text" name="name" />  
  <input type="submit" value="提交" />  
</form>  
</body>  
</html>  

在src目录下他那一个目录web,然后将该文件保存为submit.html

2、Servlet类

 

package testhttp.servlets;  
  
import java.io.BufferedWriter;  
import java.io.IOException;  
import java.io.OutputStreamWriter;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
  
import org.osgi.framework.BundleContext;  
  
public class PrintNameServlet extends HttpServlet{  
      
    private static final long serialVersionUID = -9080875068147052401L;  
      
    private BundleContext context;  
      
    public PrintNameServlet(BundleContext context) {  
        super();  
        this.context = context;  
    }  
  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        doGet(req, resp);  
    }  
      
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
          
        resp.setCharacterEncoding("UTF-8");  
          
        String name = req.getParameter("name");  
        System.out.println(name);  
          
        String s = "";  
        if(name==null||"".equals(name.trim())){  
            s = "你没有输入名字";  
        }else{  
            s = "你输入的名字是:"+name.trim();  
        }  
        StringBuilder sb = new StringBuilder();  
        sb.append("<html><title>Response</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />");  
        sb.append("<body>");  
        sb.append(s);  
        sb.append("</body></html>");  
          
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(resp.getOutputStream(),"UTF-8"));  
        bw.write(sb.toString());  
        bw.flush();  
        bw.close();  
    }  
  
}  

3、注册

页面也有了,servlet类也有了,下面就是将他们注册入HttpService里了。假如在我们的bundle一运行,这些http页面就可用,那么,我们可又在Activator里注册服务。

 

  • 取得HttpService对象

        private HttpService service;

 

public void start(BundleContext bundleContext) throws Exception {  
    Activator.context = bundleContext;  
    ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName());  
    service = (HttpService) bundleContext.getService(serviceReference);  
}  

 这是一个例行公事般的步骤,一般取得一个特定服务的代码都可又这么实现。

  • 注册页面和Servlet

          有了HttpService对象,然后就是注册资源和servlet到这个HttpService对象:

 

public void start(BundleContext bundleContext) throws Exception {  
    Activator.context = bundleContext;  
    ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName());  
    service = (HttpService) bundleContext.getService(serviceReference);  
  
               //register  
    HttpContext httpContext = service.createDefaultHttpContext();  
      
    service.registerResources("/osgi", "/web", httpContext); //设置别名,所有对"/osgi"映射到"web"目录  
    service.registerServlet("/osgi/print", new PrintNameServlet(bundleContext)  
    , null, httpContext);   //设置servlet别名,‘/osgi/print"映射到servlet的实现  
}  
  •  退出时移除别名

 

public void stop(BundleContext bundleContext) throws Exception {  
    service.unregister("/osgi/print");  
    service.unregister("/osgi");  
    Activator.context = null;  
}  
  • 启动bundle

          示例bundle已经准备好,最后就是启动这个bundle了,只需要在第一节的bundle列表中把这个bundle添加进去就可又了:

 技术图片

如果没有意外,访问 http://localhost:8080/osgi/submit.html 

 技术图片

 

 如果能看到这个页面,那基本就是成功了,输入"刘刚",提交后,返回结果为:

 技术图片

 

 技术图片

 

以上是关于在OSGI容器Equinox中嵌入HttpServer的主要内容,如果未能解决你的问题,请参考以下文章

在 Equinox 中运行 Arquillian

关闭 OSGi 容器的最佳方法(特别是 Equinox)

以编程方式启动 OSGi(Equinox)?

使用 Hibernate Unmanaged JPA 在 Equinox OSGI 框架中获取 EntityManagerFactory

Persistence.xml 和 OSGi (Equinox)

哪个版本的 Eclipse/Equinox 实现了哪个版本的 OSGi?