本文将一步一步对OSGi Web应用开发的技巧进行讲解,包括程序注册方式和声明方式。在阅读完本文之后,相信读者便能够初步掌握OSGi Web应用的开发过程。

【51CTO精选译文】在《你好,OSGi》的之前一篇文章中,咱们介绍了OSGi Web运用开发工具Equinox的装备办法,在这一篇中,咱们会进行Hello World OSGi Web运用程序的开发。该操练中的运用程序是一个包括了两个资源的 OSGi 套件。***个是 helloworld.html,它是一个静态的 HTML 文件;第二个是 HelloWorldServlet,它是一个 HttpServlet。有一个要点需注意,OSGi 容器供给 HttpService 服务。每个想要处理 HTTP 恳求的套件都将调用该服务上的办法来告诉 OSGi 容器它可以处理哪些 URL。将 URL 注册为 OSGi 套件可处理,存在两种办法:

打造一个Hello World OSGi Web应用程序(开发helloworld程序)  Web应用 第1张

51CTO修正引荐:OSGi入门与实践全攻略

程序办法:***检索来自 OSGi 的服务寄存器 HttpService,然后调用其上的办法将恳求 URL 注册为套件可处理。

声明办法:在 plugin.xml 文件中界说套件可处理的恳求 URL。

咱们将一步一步地对这些技巧进行解说,先从程序注册办法开端。

程序注册办法

依照下面的过程,可运用程序办法将 URL 注册为插件可处理。

你首要应做的是参与一个新的 OSGi 插件,命名为com.javaworld.sample.OSGi.web.programmatic。(有关在 Eclipse 中创立 OSGi 插件的更多信息,请查阅本系列的***节。)

翻开 com.javaworld.sample.osgi.web.programmatic 的 MANIFEST.MF 文件并对其进行修正,导入 javax.servlet, javax.servlet.http, org.osgi.service.http 和org.osgi.util.tracker 包。更改完结之后,你的 MANIFEST.MF 应如列表 3 相似。

列表 3. 程序式插件的 MANIFEST.MF 文件

  1. Manifest-Version:1.0
  2. Bundle-ManifestVersion:2
  3. Bundle-Name:WebappPlug-in
  4. Bundle-SymbolicName:com.javaworld.sample.osgi.web.programmatic
  5. Bundle-Version:1.0.0
  6. Bundle-Activator:com.javaworld.sample.osgi.web.webapp.Activator
  7. Bundle-Vendor:JAVAWORLD
  8. Bundle-Localization:plugin
  9. Import-Package:javax.servlet;version="2.4.0",
  10. javax.servlet.http;version="2.4.0",
  11. org.osgi.framework;version="1.3.0",
  12. org.osgi.service.http;version="1.2.0",
  13. org.osgi.util.tracker;version="1.3.2"

如你所见,Import-Package 清单头的值界说了你需求导入的包列表。

在插件的根目录创立一个简略的 helloworld.html 文件,如列表 4 所示。该文件用来显现音讯“Hello From helloworld.html”。

列表 4. helloworld.html

  1. <!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <head>
  4. <metahttp-equiv="Content-Type"content="text/html;charset=ISO-8859-1">
  5. <title>HelloWorldOSGiWeb</title>
  6. </head>
  7. <body>
  8. <h3>HelloFromhelloworld.html</h3>
  9. </body>
  10. </html>

下一步,创立如列表 5 所示的 HelloWorldServlet。

列表 5. HelloWorldServlet

  1. packagecom.javaworld.sample.osgi.web.webapp;
  2. importjava.io.IOException;
  3. importjavax.servlet.ServletException;
  4. importjavax.servlet.http.HttpServlet;
  5. importjavax.servlet.http.HttpServletRequest;
  6. importjavax.servlet.http.HttpServletResponse;
  7. publicclassHelloWorldServletextendsHttpServlet{
  8. protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{
  9. resp.setContentType("text/html");
  10. resp.getWriter().println("<h3>HellofromHelloWorldServlet</h3>");
  11. }
  12. }

HelloWorldServlet 类对 HttpServlet 进行扩展并重写其 doGet() 办法。新的 doGet() 办法仅有的操作就是在输出中写入“Hello from HelloWorldServlet”。

下一步,你需求在 com.javaworld.sample.osgi.web.programmatic 插件发动时履行相同的代码。Activator.java 将作为该插件的套件的激活器(Activator),如列表 6 所示。

列表 6. Activator.java

  1. importorg.osgi.framework.BundleActivator;
  2. importorg.osgi.framework.BundleContext;
  3. importorg.osgi.util.tracker.ServiceTracker;
  4. publicclassActivatorimplementsBundleActivator{
  5. ServiceTrackerhttpServiceTracker;
  6. publicvoidstart(BundleContextcontext)throwsException{
  7. System.out.println("HelloWorld!!");
  8. httpServiceTracker=newHttpServiceTracker(context);
  9. httpServiceTracker.open();
  10. }
  11. publicvoidstop(BundleContextcontext)throwsException{
  12. System.out.println("GoodbyeWorld!!");
  13. httpServiceTracker.close();
  14. httpServiceTracker=null;
  15. }
  16. }

Activator 类对 BundleActivator 进行扩展并完结了两个办法:

start():当 OSGi 容器发动该插件时调用 start() 办法。在start()HttpServiceTracker 类 的一个方针;这是你用来盯梢 HttpService 的 ServiceTracker 类。一旦你具有了 HttpService 类的一个方针,可以调用它的 open() 办法来开端盯梢 HttpService。

stop():当封闭插件时,OSGi 容器调用 stop() 办法。在 stop() 办法内,你调用 HttpServiceTracker 方针的 close() 办法来停止盯梢 HttpService。

***一步是创立 HttpServiceTracker 类,如列表 7 所示。

列表 7. HttpServiceTracker

  1. importorg.osgi.framework.BundleContext;
  2. importorg.osgi.framework.ServiceReference;
  3. importorg.osgi.service.http.HttpService;
  4. importorg.osgi.util.tracker.ServiceTracker;
  5. publicclassHttpServiceTrackerextendsServiceTracker{
  6. publicHttpServiceTracker(BundleContextcontext){
  7. super(context,HttpService.class.getName(),null);
  8. }
  9. publicObjectaddingService(ServiceReferencereference){
  10. HttpServicehttpService=(HttpService)context.getService(reference);
  11. try{
  12. httpService.registerResources("/helloworld.html","/helloworld.html",null);
  13. httpService.registerServlet("/helloworld",newHelloWorldServlet(),null,null);
  14. }catch(Exceptione){
  15. e.printStackTrace();
  16. }
  17. returnhttpService;
  18. }
  19. publicvoidremovedService(ServiceReferencereference,Objectservice){
  20. HttpServicehttpService=(HttpService)service;
  21. httpService.unregister("/helloworld.html");
  22. httpService.unregister("/helloworld");
  23. super.removedService(reference,service);
  24. }
  25. }

HttpServiceTracker 介绍

HttpService 是一项 OSGi 服务,答应 OSGi 环境中的套件动态的注册以及撤销注册 HttpService 的 URI 称号空间中的资源和 servlet —— 换句话说,行将恳求 URI 映射到一个静态 HTML 文件或一个 HttpServlet。HttpServiceTracker 类是类型 ServiceTracker 的一个方针,后者简化了对 HttpService 的盯梢。(有关 OSGi 的 ServiceTracker 的更多信息,请查阅本系列文章的***节中的“盯梢服务”。)

列表 7 中 HttpServiceTracker 类重写了两个办法:addingService() 和 removedService()。有必要对这两个办法进行解释一下:

addingService()

一个回调办法,一旦 HttpService 可用时将对其调用。在这个办法中,首要调用 HttpService.registerResources("/helloworld.html", "/helloworld.html", null),将 helloworld.html 文件映射到 /helloworld.html。之后,每逢你恳求 http://localhost/helloworld.html 时, HttpService 将为用户供给 helloworld.html。请注意,你无需将 helloworld.html 映射到 /helloworld.html URL;文件名无需匹配该地址,并且你可以将其映射到相似 /test.html 的文件上。

假如想要在你的插件中供给(serve)多个 HTML 文件,你需求创立多个目录。假如想要一个 /html 目录,可以经过调用 HttpService.registerResources("/html", "/html", null) 来注册它。然后,假如你还想要拜访 html 文件夹中的 test.htm,相应的地址是 http://localhost/html/test.html。registerServlet() 办法用于将 URL 映射到 HttpServlet 类。在这个简略的代码中,使用对 registerServlet("/helloworld", new HelloWorldServlet(), null, null) 的调用将 /helloworld URL 映射到 HelloWorldServlet 类。如需将初始化参数传递到你的 HttpServlet,你可以创立一个 java.util.Dictionary 方针并将其作为第三方自变量传递到 registerServlet()。

removedService()

每逢重写你的 ServiceTracker 中的 addingService() 办法来取得一个服务时,仍是重写 removedService() 来撤销该服务。在 removedService() 办法内,你调用 unregister() 办法来撤销注册 /helloworld.html 和 /helloworld URI。这将告诉 HttpService :com.javaworld.sample.osgi.web.programmatic 不再想要为指定 URL 供给恳求服务。假如你调用 unregister() 办法来撤销对 servlet 的注册, 该 servlet 的 destroy() 办法将被调用以便对其本身进行铲除。

现在,HelloWorld OSGi Web运用程序现已准备就绪,并且你可以在 Equinox OSGi 结构中履行你悉数的套件。你应该可以经过 http://localhost/helloworld.html 拜访 helloworld.html,以及经过 http://localhost/helloworld 拜访 HelloWorld 的servlet。

声明注册办法

你或许现已注意到,经过程序办法将恳求 URL 注册为 OSGi 创立可处理,相应的工作流并不小。并且,假如想要更改 helloworld.html 的 URL(比如从 /helloworld.html 更改到 /hello.html),你将不得不更新 HttpServiceTracker.java,从头编译代码,然后在 OSGi 容器中对其进行布置。下面,咱们来看看声明办法,它略微简略点。

1. 创立一个新的插件项目,com.javaworld.sample.osgi.web.declarative。挑选 OSGi Equinox 结构作为方针渠道。

2. 修正 com.javaworld.sample.osgi.web.declarative 套件的 MANFIEST.MF 文件,导入 javax.servlet 和 javax.servlet.http 包并将 org.eclipse.equinox.http.registry 设置为该套件的被恳求套件。完结这项修正之后,你的 MANIFEST.MF 文件将与列表 8 相似。

列表 8. 声明办法插件的 MANIFEST.MF 文件

  1. Manifest-Version:1.0
  2. Bundle-ManifestVersion:2
  3. Bundle-Name:DeclarativePlug-in
  4. Bundle-SymbolicName:com.javaworld.sample.osgi.web.declarative;singleton:=true
  5. Bundle-Version:1.0.0
  6. Bundle-Vendor:JAVAWORLD
  7. Bundle-Localization:plugin
  8. Import-Package:javax.servlet;version="2.4.0",
  9. javax.servlet.http;version="2.4.0"
  10. Require-Bundle:org.eclipse.equinox.http.registry

这个 Require-Bundle 清单头包括一个套件符号名的列表,在对导入查找之后并且在套件途径查找之前,需对其进行查找。不过,对其恳求套件,只要那些标记为经过被恳求套件导出的包才是可见的。

3. 从 com.javaworld.sample.osgi.web.programmatic 套件将 helloworld.html 和 HelloWorldServlet.java 复制到 com.javaworld.sample.osgi.web.declarative 套件。

4. ***,更改 com.javaworld.sample.osgi.web.declarative 套件的 plugin.xml 文件,将一切恳求注册为它可以处理,如列表 9 所示。

Listing 9. plugin.xml

  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <?eclipseversion="3.0"?>
  3. <plugin>
  4. &lt
转载请说明出处
知优网 » 打造一个Hello World OSGi Web应用程序(开发helloworld程序)

发表评论

您需要后才能发表评论