Java OSGi中使用在后台运行的REST web服务的网站
我花了好几天的时间试图弄清楚如何在OSGi中添加一个网站 我有一个运行Jetty扩展的Restlet web服务,将Jetty用作连接器。此功能在多个URL下提供不同的资源 但我也希望有一个小网站上运行的系统,可以由用户访问。我想使用一些HTML、Javascript、CSS,并用一些图形和图片提供当前的数据状态 我假设因为Jetty是在后台运行的,所以我能够在Jetty上部署这个网站,并可能调用Javascript中Restlet提供的服务器资源 显然,除了restlet服务之外,没有任何东西起作用 我的问题是,是否可以添加一个WAB包并期望它工作(因为Jetty是在后台运行的)?或者有没有更好的方法在OSGi中添加网站? 或 我现在唯一的选择是,因为可以返回一个HTML表单作为表示,所以可以在HTML表单中添加所有javascript代码,并将其作为GET请求的响应发送(我认为这是一个混乱) 一切都将运行在覆盆子皮,所以我只能有一个非常小的足迹。我使用的是Equinox、Restlet 2.3.0和Jetty 9.2.6Java OSGi中使用在后台运行的REST web服务的网站,java,web,jetty,osgi,restlet,Java,Web,Jetty,Osgi,Restlet,我花了好几天的时间试图弄清楚如何在OSGi中添加一个网站 我有一个运行Jetty扩展的Restlet web服务,将Jetty用作连接器。此功能在多个URL下提供不同的资源 但我也希望有一个小网站上运行的系统,可以由用户访问。我想使用一些HTML、Javascript、CSS,并用一些图形和图片提供当前的数据状态 我假设因为Jetty是在后台运行的,所以我能够在Jetty上部署这个网站,并可能调用Javascript中Restlet提供的服务器资源 显然,除了restlet服务之外,没有任何东西
如果有人知道一个链接,我会非常感激,在这个链接中,我可以获得至少一个在OSGi中运行的示例页面的信息。我尝试了很多,但都没有成功。我建议您看看在Apache Karaf()中是如何实现的。更多关于ApacheKaraf和WebContainers的信息,请点击此处:事实上,Jetty通过其连接器功能在内部由Restlet在引擎盖下使用。这样,动态注册应用程序并不方便(也不是正确的方法) 也就是说,Restlet非常灵活和动态。这意味着您可以以与WAB捆绑包类似的方式动态处理包含Restlet应用程序的捆绑包,即将它们连接到组件的虚拟主机 以下是实现这一点的方法:
- 创建一个bundle,将Restlet组件放入OSGi容器中。您应该利用
监听器,使所有连接器、转换器等都能够。。。已注册到Restlet引擎中:FrameworkListener
private Component component; public void start(BundleContext bundleContext) throws Exception { bundleContext.addFrameworkListener(new FrameworkListener() { component = new Component(); (...) component.start(); }); } public void stop(BundleContext bundleContext) throws Exception { component.stop(); }
- 当组件启动时,您可以查找容器中存在的包以及包含的Restlet应用程序。对于这种类型的每一个包,您都可以注册一个专用的OSGi服务,使您想要针对组件注册的内部Restlet应用程序可用
针对组件注册应用程序是非常困难的ServiceReference[] restletAppRefs = bundleContext.getServiceReferences( "restletApplication", null); if (restletAppsRefs != null) { for (ServiceReference restletAppRef : restletAppsRefs) { RestletApplicationService descriptor = (RestletApplicationService) bundleContext .getService(serviceReference); String path = descriptor.getPath(); Application restletApplication = descriptor.getApplication(); // Register the application against the component (...) } }
try { VirtualHost virtualHost = getExistingVirtualHost( component, hostDomain, hostPort); if (virtualHost == null) { virtualHost = new VirtualHost(); virtualHost.setHostDomain(hostDomain); virtualHost.setHostPort(hostPort); component.getHosts().add(virtualHost); } Context context = component.getContext().createChildContext(); virtualHost.setContext(context); virtualHost.attachDefault(application); component.updateHosts(); application.start(); } catch(Exception ex) { (...) }
- 您还需要考虑OSGi的动态性。我的意思是,包可以在OSGi容器本身启动之后来来去去。你可以利用
bundleContext.addServiceListener(new ServiceListener() { public void serviceChanged(ServiceEvent event) { if (isServiceClass(event, RestletApplicationService)) { int type = event.getType(); if (type == ServiceEvent.REGISTERED) { // Register the Restlet application against the component } else if (type == ServiceEvent.UNREGISTERING) { // Unregister the Restlet application } } } });
Thierry您可以选择很多选项—OSGi并没有对您的操作施加太多限制。如果您想使用OSGi的功能,那么这里有几个想法:
- 一种选择是部署WAB。您需要确保您的框架运行了必要的OSGi服务。仅仅因为某些捆绑包在内部使用Jetty,并不意味着必要的OSGi服务正在运行李>
- 另一种选择是直接使用OSGi Http服务(同样,您需要包括一个实现此服务的包(如前面提到的Felix包)。调用
将提供包内的静态内容org.OSGi.service.Http.HttpService.registerResources()
Pr>另一种选择是采取以码头为中心的观点。REST的嵌入式Jetty可能不被配置为从磁盘上提供任意内容。您可以查看重新配置嵌入式码头来做这件事,或者考虑将Restle部署到“标准”码头安装。个人而言,我会尝试后者。谢谢您的支持。响应。但我已经有一个基于Restlet的完整服务在运行。我已经创建了组件,注册了应用程序,并使用相应的url向不同的资源类添加了一个路由。问题在于为网站提供了一个漂亮的用户界面,可以总结和显示状态(通过访问不同的资源url并添加一些javascript、css…)。我目前使用FreeMarker,我通过FreeMarker将网站作为html表单表示返回。但这与html表单的概念背道而驰。我想让网站html直接可访问,正如您在部署WAB的第一个选项中所说的,我需要有必要的捆绑包,这是我的问题之一。确定并实现ancies是一个令人头痛的问题,因为在J2SE选项下没有关于equinox的明确指南。我将在周末尝试org.apache.felix.http.jetty,但我认为这同样伴随着对其他felix捆绑包的一系列其他依赖。至于第二个问题,甚至jetty都建议在OSGi中嵌入jetty,而不是在jetty上部署应用程序。