Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OSGi中使用在后台运行的REST web服务的网站_Java_Web_Jetty_Osgi_Restlet - Fatal编程技术网

Java OSGi中使用在后台运行的REST web服务的网站

Java 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中添加一个网站

我有一个运行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.6


如果有人知道一个链接,我会非常感激,在这个链接中,我可以获得至少一个在OSGi中运行的示例页面的信息。我尝试了很多,但都没有成功。

我建议您看看在Apache Karaf()中是如何实现的。更多关于ApacheKaraf和WebContainers的信息,请点击此处:

事实上,Jetty通过其连接器功能在内部由Restlet在引擎盖下使用。这样,动态注册应用程序并不方便(也不是正确的方法)

也就是说,Restlet非常灵活和动态。这意味着您可以以与WAB捆绑包类似的方式动态处理包含Restlet应用程序的捆绑包,即将它们连接到组件的虚拟主机

以下是实现这一点的方法:

  • 创建一个bundle,将Restlet组件放入OSGi容器中。您应该利用
    FrameworkListener
    监听器,使所有连接器、转换器等都能够。。。已注册到Restlet引擎中:

    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服务正在运行
捆绑包org.apache.felix.http.jetty确实提供了部署WAB所需的服务。版本2.2.2在磁盘上为1.3MB,并嵌入了自己的Jetty副本。其他实现也可用(例如,在Karaf中使用的Pax Web,也嵌入Jetty)

  • 另一种选择是直接使用OSGi Http服务(同样,您需要包括一个实现此服务的包(如前面提到的Felix包)。调用
    org.OSGi.service.Http.HttpService.registerResources()
    将提供包内的静态内容
如果这个额外的内存占用是一个真正的问题,那么您可能想看看如何让Restlet使用osgihttp服务,而不是通过嵌入式Jetty提供自己的服务


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上部署应用程序。