码头:将对象从具有WebAppProvider的主要方法传递给Servlet [英] Jetty: Pass object from main method with WebAppProvider to Servlet

查看:247
本文介绍了码头:将对象从具有WebAppProvider的主要方法传递给Servlet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要以一种主要方法传递嵌入式码头代码中的对象,以便在servlet中使用。



这是一个问题,因为使用了单独的类加载器



我的主要代码设置如下:



< pre class = lang-java prettyprint-override> Server server = new Server();
//在此处设置连接器...
ContextHandlerCollection contexts = new ContextHandlerCollection();
RequestLogHandler requestLogHandler = new RequestLogHandler();
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler [] {contexts,new DefaultHandler(),requestLogHandler});
server.setHandler(instrumentedHandler(handlers,metrics));

addRequestLogging(requestLogHandler);

DeploymentManager deploymentManager = new DeploymentManager();
deploymentManager.setContexts(contexts);

WebAppProvider webAppProvider =新的WebAppProvider();
webAppProvider.setMonitoredDirName(jettyHome + / webapps);
webAppProvider.setParentLoaderPriority(false);
webAppProvider.setExtractWars(true);
webAppProvider.setScanInterval(1);
webAppProvider.setDefaultsDescriptor(jettyHome + /webdefault.xml);
webAppProvider.setConfigurationManager(new PropertiesConfigurationManager());

deploymentManager.addAppProvider(webAppProvider);
server.addBean(deploymentManager);
//尝试在服务器上设置指标-但我无法在Servlet
server.setAttribute(MetricRegistry.class.getName(),metrics)中访问它们;
server.start();
server.join();

我尝试了一些问题,但它们不起作用。具体来说,在Servlet上下文中没有设置 org.eclipse.jetty.server.Server 属性。



(具体来说,我正在尝试在码头对象上设置dropwizard指标,但是我的其余应用程序需要相同的MetricRegistry对象,以便可以将所有指标和报告者放在一起)

解决方案

使用 DeploymentManager 时,您无权访问 WebAppContext ,或者在主要起始代码中输入 ServletContextHandler ContextHandler



您必须使用 DeploymentManager 中的功能来提供自定义的 AppLifeCycle.Binding



奖金是,这在热(重新)部署期间也能起作用。



这是嵌入式喷气式烹饪书



DeployWebApps.java

  package org.eclipse.jetty.cookbook; 

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

进口org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;

公共类DeployWebApps
{
public static void main(String [] args)引发异常
{
服务器服务器=新服务器(8080);

ContextHandlerCollection contexts = new ContextHandlerCollection();
HandlerCollection handlers = new HandlerCollection();

handlers.setHandlers(new Handler [] {contexts,new DefaultHandler()});

server.setHandler(handlers);

路径confFile = Paths.get(System.getProperty( user.dir), example.conf);

ContextAttributeCustomizer contextAttributeCustomizer = new ContextAttributeCustomizer();
contextAttributeCustomizer.setAttribute( common.conf,confFile);

DeploymentManager deploymentManager = new DeploymentManager();
deploymentManager.setContexts(contexts);
deploymentManager.addLifeCycleBinding(contextAttributeCustomizer);

字符串jettyBaseProp = System.getProperty( jetty.base);
if(jettyBaseProp == null)
{
抛出新的FileNotFoundException(缺少系统属性'jetty.base');
}
路径jettyBase = new File(jettyBaseProp).toPath()。toAbsolutePath();

WebAppProvider webAppProvider =新的WebAppProvider();
webAppProvider.setMonitoredDirName(jettyBase.resolve( webapps)。toString());

deploymentManager.addAppProvider(webAppProvider);
server.addBean(deploymentManager);

//让启动后转储服务器。
//我们可以查找已部署的上下文,并在转储部分的处理程序属性中查找ContextAttributesCustomizer的
//示例。
server.setDumpAfterStart(true);
server.start();
server.join();
}

公共静态类ContextAttributeCustomizer实现AppLifeCycle.Binding
{
public final Map< String,Object>属性=新的HashMap<>();

public void setAttribute(字符串名称,对象值)
{
this.attributes.put(名称,值);
}

@Override
public String [] getBindingTargets()
{
return new String [] {AppLifeCycle.DEPLOYING};
}

@Override
public void processBinding(节点节点,应用程序应用)引发异常
{
ContextHandler handler = app.getContextHandler();
if(handler == null)
{
throw new NullPointerException(没有为应用程序创建处理程序: +应用程序);
}
属性.forEach((名称,值)-> handler.setAttribute(名称,值));
}
}
}


I need to pass an object from the embedded jetty code in a main method to be used in a servlet.

This is an issue because of the separate classloader used within the WebAppContext - otherwise I would just use a static variable.

My main code sets things up like this:

Server server = new Server(); 
// setup connectors here...
ContextHandlerCollection contexts = new ContextHandlerCollection();
RequestLogHandler requestLogHandler = new RequestLogHandler();
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[] { contexts, new DefaultHandler(), requestLogHandler });
server.setHandler(instrumentedHandler(handlers, metrics));

addRequestLogging(requestLogHandler);

DeploymentManager deploymentManager = new DeploymentManager();
deploymentManager.setContexts(contexts);

WebAppProvider webAppProvider = new WebAppProvider();
webAppProvider.setMonitoredDirName(jettyHome + "/webapps");
webAppProvider.setParentLoaderPriority(false);
webAppProvider.setExtractWars(true);
webAppProvider.setScanInterval(1);
webAppProvider.setDefaultsDescriptor(jettyHome + "/webdefault.xml");
webAppProvider.setConfigurationManager(new PropertiesConfigurationManager());

deploymentManager.addAppProvider(webAppProvider);
server.addBean(deploymentManager);
// Attempt to set the metrics on the server - but I can't access them in the Servlet
server.setAttribute(MetricRegistry.class.getName(), metrics);
server.start();
server.join();

I tried a few things from this question, but they did not work. Specifically, there is no org.eclipse.jetty.server.Server attribute set on the servlet context.

(Specifically, I am trying to setup dropwizard metrics on the jetty objects, but I need the same MetricRegistry object for the rest of my application so I can keep all my metrics and reporters together)

解决方案

When using the DeploymentManager, you have no access to the WebAppContext, or ServletContextHandler, or ContextHandler during your main start code.

You'll instead have to use the facilities in the DeploymentManager to provide a custom AppLifeCycle.Binding that does what you need it to do during the deployment phases.

Bonus is that this works during hot (re)deploy as well.

Here's a working example of this setup in embedded-jetty from the embedded-jetty-cookbook

DeployWebApps.java

package org.eclipse.jetty.cookbook;

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;

public class DeployWebApps
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);

        ContextHandlerCollection contexts = new ContextHandlerCollection();
        HandlerCollection handlers = new HandlerCollection();

        handlers.setHandlers(new Handler[]{contexts, new DefaultHandler()});

        server.setHandler(handlers);

        Path confFile = Paths.get(System.getProperty("user.dir"), "example.conf");

        ContextAttributeCustomizer contextAttributeCustomizer = new ContextAttributeCustomizer();
        contextAttributeCustomizer.setAttribute("common.conf", confFile);

        DeploymentManager deploymentManager = new DeploymentManager();
        deploymentManager.setContexts(contexts);
        deploymentManager.addLifeCycleBinding(contextAttributeCustomizer);

        String jettyBaseProp = System.getProperty("jetty.base");
        if (jettyBaseProp == null)
        {
            throw new FileNotFoundException("Missing System Property 'jetty.base'");
        }
        Path jettyBase = new File(jettyBaseProp).toPath().toAbsolutePath();

        WebAppProvider webAppProvider = new WebAppProvider();
        webAppProvider.setMonitoredDirName(jettyBase.resolve("webapps").toString());

        deploymentManager.addAppProvider(webAppProvider);
        server.addBean(deploymentManager);

        // Lets dump the server after start.
        // We can look for the deployed contexts, along with an example of the
        // result of ContextAttributesCustomizer in the dump section for "Handler attributes"
        server.setDumpAfterStart(true);
        server.start();
        server.join();
    }

    public static class ContextAttributeCustomizer implements AppLifeCycle.Binding
    {
        public final Map<String, Object> attributes = new HashMap<>();

        public void setAttribute(String name, Object value)
        {
            this.attributes.put(name, value);
        }

        @Override
        public String[] getBindingTargets()
        {
            return new String[]{ AppLifeCycle.DEPLOYING };
        }

        @Override
        public void processBinding(Node node, App app) throws Exception
        {
            ContextHandler handler = app.getContextHandler();
            if (handler == null)
            {
                throw new NullPointerException("No Handler created for App: " + app);
            }
            attributes.forEach((name, value) -> handler.setAttribute(name, value));
        }
    }
}

这篇关于码头:将对象从具有WebAppProvider的主要方法传递给Servlet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆