我已经构建了一个通过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可供构建。
您仍然可以访问标准的HttpServletRequest
和HttpServletResponse
,以及它们提供的异步处理和I/O。但是,您还可以访问原始内部Request
对象,该对象提供了比HttpServletRequest
更多的功能。
顺便说一句,现在许多基于servlet的应用程序都支持插件。大多数使用ControllerServlet、Filters或ServletContext的注册操作来实现这一点。