Maven构建OSGI+HttpServer应用

Maven构建OSGI+HttpServer应用

官网(https://eclipse.dev/equinox/server/http_in_equinox.php)介绍有两种方式:

Maven构建OSGI+HttpServer应用_第1张图片

一种是基于”org.eclipse.equinox.http”包的轻量级实现,另一种是基于”org.eclipse.equinox.http.jetty”包(基于jetty的Servlet)实现。

使用 "org.eclipse.equinox.http" 包(例如:http-1.0.100-v20070423.jar),可以将我们自定义的服务(servlet或静态资源页面)注册到这个 HttpService 中去,实现自定义的HTTP服务。

"org.osgi.service.http" 包(例如:org.osgi.service.http-1.2.2.jar)内部会内嵌一个 HttpService Interface,而"org.eclipse.equinox.http" 包(http-1.0.100-v20070423.jar)提供了一个上述Interface的 HttpService实现类,因此,一旦这个osgi bundle (http-1.0.100-v20070423.jar)启动了,就会有一个内嵌的 http 服务被启动,默认地址是 http://localhost,端口为 80,可以通过指定参数 “org.osgi.service.http.port”来修改默认端口。
Maven构建OSGI+HttpServer应用_第2张图片

"org.eclipse.equinox.http" 包(http-1.0.100-v20070423.jar)内有一个上面那个 HttpService Interface 的实现类:

Maven构建OSGI+HttpServer应用_第3张图片

想要提供我们自定义的 HttpService服务,就要将我们的服务(servlet或静态资源页面)注册到这个 HttpService 中去,需要用到 "org.osgi.service.http" 包中的 HttpService 类的两个注册方法:

1)注册静态资源:
registerResources(String alias, String name, HttpContext httpContext)

2)注册 Servlet 类:
registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext httpContext)

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

提供自定义的WebService实现的步骤如下:
1)获取 httpService 对象;
2)编码提供 servlet 和 webpage 的实现;
3)将 servlet 和 webpage 注册到 HttpService 服务中去(同时指定对应的 alias);
4)访问;

新建manve项目:
Maven构建OSGI+HttpServer应用_第4张图片

创建package、class、和编码:
1)Java package:com.xxx.osgi.httpserver.demo、com.xxx.osgi.httpserver.servlet
2)Java class文件:Activator.java、MyServlet.java

Activator.java:

package com.xxx.osgi.httpserver.demo;

import com.xxx.osgi.httpserver.servlet.MyServlet;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;

import java.util.LinkedList;
import java.util.List;

/**
 * @author Frank
 * @date 2023/12/26
 */
public class Activator implements BundleActivator {
    private static BundleContext bundleContext;
    private HttpService httpService;
    private List bundles;
   
    static BundleContext getBundleContext() {
        return bundleContext;
    }

    public void start(BundleContext bundleContext) throws Exception {
        Activator.bundleContext = bundleContext;
        installBundles(bundleContext, false); // install other bundles
        ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName());
        httpService = (HttpService) bundleContext.getService(serviceReference);

        // 注册
        HttpContext httpContext = httpService.createDefaultHttpContext();

        // 注册静态页面,设置别名"/osgi",所有对"/osgi"的请求映射到"/webpage/index.html"
        httpService.registerResources("/osgi", "/webpage/index.html", httpContext);
        System.out.println("start ok");

        // 注册 servlet,设置servlet别名"/test",所有对'/test"的请求映射到myServlet的实现
        MyServlet myServlet = new MyServlet();
        httpService.registerServlet("/test", myServlet, null, httpContext);
    }

    public void stop(BundleContext bundleContext) throws Exception {
        installBundles(bundleContext, true); //uninstall other bundles
        httpService.unregister("/osgi");
        httpService.unregister("/test");
        Activator.bundleContext = null;
        System.out.println("stop ok");
    }

    public void installBundles(BundleContext context, boolean uninstall) {
        List bundleFiles = new LinkedList();
        List installedBundles = new LinkedList();
        //install my other bundles
        // System.out.printf("1 %s\n", FileLocator.getBundleFile(FrameworkUtil.getBundle(Activator.class)).getAbsolutePath());
        // System.out.printf("2 %s\n", FileLocator.getBundleFile(context.getBundle()).getAbsolutePath());
        // System.out.printf("3 %s\n", context.getBundle().getLocation());

        // String baseDir = FileLocator.getBundleFile(context.getBundle()).getParentFile().getAbsolutePath();
        String baseDir = context.getBundle().getLocation().replaceFirst("/[^/]*.jar","/");
        bundleFiles.add(baseDir + "helloworld-server-1.0.0-SNAPSHOT.jar");
        if (!uninstall) {
            // install & start bundles
            for (String bundleFile : bundleFiles) {
                try {
                    Bundle bundle = context.installBundle(bundleFile);
                    installedBundles.add(bundle);
                    bundle.start();
                } catch (BundleException e) {
                    if (!e.getMessage().contains("A bundle is already installed")) {
                        throw new RuntimeException(e);
                    }
                }
            }
            bundles = installedBundles;
            System.out.printf("all bundles (cnt = %d) installed and started!", bundles.size());
        } else {
            // stop & uninstall bundles
            for (Bundle bundle : bundles) {
                try {
                    context.getBundle(bundle.getBundleId()).stop();
                    context.getBundle(bundle.getBundleId()).uninstall();
                } catch (BundleException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.printf("all bundles (cnt = %d) stopped and uninstalled!", bundles.size());
        }
    }
}

MyServlet.java:

package com.xxx.osgi.httpserver.servlet;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;

public class MyServlet extends HttpServlet implements Servlet {
    
    private Logger logger = Logger.getLogger(this.getClass().getName());

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("MyServlet return: Method=" + req.getMethod() + ", URI=" + req.getRequestURI());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("MyServlet return: Method=" + req.getMethod() + ", URI=" + req.getRequestURI());
    }
}

3)创建静态页面文件:webpage/index.html




    
    jetty test


OSGI HttpServer/Jetty Test

register static resource/pages:
registerResources(String alias, String name, HttpContext httpContext)

register servlet class:
registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext httpContext)

4)创建&编辑 pom.xml 文件

pom文件中定义了OSGI框架和版本、编码中所需的依赖以及osgi menifest和osgi打包配置:


  4.0.0

  com.xxx.osgi
  osgi-httpserver-demo
  1.0.0-SNAPSHOT
  bundle

  osgi-httpserver-demo
  http://maven.apache.org

  
    UTF-8
    1.8
    1.8
    1.8
  

  

    
      
      
      
      
      org.eclipse
      osgi
      3.10.0-v20140606-1445
      provided
    

    
    
    
      org.osgi
      org.osgi.service.cm
      1.6.1
    
    
    
      org.eclipse.jetty.orbit
      javax.servlet
      3.0.0.v201112011016
    
    
    
      org.eclipse.equinox
      http
      1.0.100-v20070423
    
    
    
      org.osgi
      org.osgi.service.http
      1.2.2
    
    

    
    
    
      org.eclipse.equinox
      common
      3.6.200-v20130402-1505
    

  

  
    
      
        
        
        org.apache.felix
        maven-bundle-plugin
        3.5.0
        true

        
          
            
            *;scope=compile|runtime
            lib
            true

            
            webpage=webpage
            

            .,{maven-dependencies}
            ${project.name}
            $(replace;${project.artifactId};-;_)
            ${project.version}
            com.xxx.osgi.httpserver.demo.Activator
            *
            
              javax.servlet,
              javax.servlet.http,
              org.osgi.service.http;resolution:="optional"
            
            
          
        

      
    
  

整体项目的代码结构如下:

Maven构建OSGI+HttpServer应用_第5张图片

准备运行依赖的bundles:

org.osgi.service.cm_1.6.1.202109301733.jar
javax.servlet-3.0.0.v201112011016.jar
org.osgi.service.http-1.2.2.jar
http-1.0.100-v20070423.jar
 

直接在 configuration/config.ini 初始化启动配置中加入依赖 bundles 或者启动 osgi 以后执行 install 安装依赖 bundles:
install plugins/org.osgi.service.cm_1.6.1.202109301733.jar
install other_bundles/javax.servlet-3.0.0.v201112011016.jar
install other_bundles/org.osgi.service.http-1.2.2.jar
install other_bundles/http-1.0.100-v20070423.jar
start 5 6 7 8 

注意,多条命名install时有先后顺序依赖,也可以放在一条命令执行多个 bundle 的install(无顺序依赖)
install plugins/org.osgi.service.cm_1.6.1.202109301733.jar other_bundles/javax.servlet-3.0.0.v201112011016.jar other_bundles/org.osgi.service.http-1.2.2.jar other_bundles/http-1.0.100-v20070423.jar
 

Maven构建OSGI+HttpServer应用_第6张图片

“org.osgi.service.http”的HttpService Interface的实现类bundle “org.eclipse.equinox.http”启动后,HttpService服务就启动了、查看HttpService监听端口已开启(如果equinox的配置文件或启动参数没有指定 org.osgi.service.http.port=8080 的话,默认是监听的是 80 端口):

Maven构建OSGI+HttpServer应用_第7张图片

项目编译打包:
执行命令打包
mvn clean package

拷贝项目编译打包生成的jar文件到osgi运行环境:

执行osgi-httpserver-demo jar包(install & start):

Maven构建OSGI+HttpServer应用_第8张图片

项目bundle 9已经启动、bundle9内代码install & start 的其他bundel 10 也都start成功,状态为ACTIVE了。

httpServer 访问测试(访问 localhost:8080/osgi 和 localhost:8080/test):
命令行访问页面:

Maven构建OSGI+HttpServer应用_第9张图片

浏览器访问页面:

Maven构建OSGI+HttpServer应用_第10张图片

你可能感兴趣的:(开发,maven,java,osgi)