Jetty:从另一个jar加载上下文



我已经构建了一个通过SPI加载多个插件的应用程序。每个插件都必须实现FrameworkPlugin接口。

public interface FrameworkPlugin {
    ...
    ContextHandler getWebContent();
    String getPluginID();
    ...
}

就是一个例子

...
ContextHandler getWebContent() {
   WebAppContext wac=new WebAppContext();
   wac.setBaseResource(new ResourceCollection(new String[] {"./src/main/webapp"}));
   return wac;
}
...

Main Project运行一个Jetty实例,所有提供基于web服务的插件都应该使用该实例。插件必须能够在自己的上下文中配置其单独的环境,除了由主项目管理的基本URL。

...
for (FrameworkPlugin p : PLUGINS) {
    ContextHandler h= p.getWebContent();
    h.setContextPath("/plugin/"+p.getPluginID().toString());
    collection.addHandler(h);
}
jettyInstance.setHandler(collection);
...

因此,从理论上讲,插件在/plugin/<id>下应该是可访问的。不幸的是,Jetty抛出了一个IllegalArgumentException,因为插件将./src/main/webapp设置为资源库,而这在主项目中并不存在。

那么,如何通过插件接口提供上下文处理程序呢?

部署WAR不是一个选项,因为加载机制无法更改。一切都必须通过使用插件接口来完成。

如果这不是一个基于WAR的项目,那么完全跳过WebAppContext的使用,只在Jetty中使用Handler系统。

WebAppContext是一个专门的Handler,旨在与遵循servlet规范的完整Web应用程序一起使用。它强制执行servlet规范强制执行的行为,从普通的(url映射顺序的行为),到黑艺术(每个元素描述符顺序查找和覆盖),再到复杂的(webapp类加载器隔离)。

Jetty中的Handler系统可以是1..n Handlers,在树中(通过HandlerCollection),有时带有Context、可变的Handler集合,并且所有这些都与服务器存在于同一类加载器中(如果您希望的话)。可以随意使用regex进行url映射,也可以自己实现级别3的URI模板。完全取决于你想用它做什么。你有许多预构建的Handlers和基本Handler可供构建。

您仍然可以访问标准的HttpServletRequestHttpServletResponse,以及它们提供的异步处理和I/O。但是,您还可以访问原始内部Request对象,该对象提供了比HttpServletRequest更多的功能。

顺便说一句,现在许多基于servlet的应用程序都支持插件。大多数使用ControllerServlet、Filters或ServletContext的注册操作来实现这一点。

最新更新