Tomcat 8 webapp,动态添加PostResources

时间:2016-01-07 14:10:35

标签: servlets tomcat8

我有一个webapp,它使用一个监听器来动态添加servlet实例。 每个servlet实例由用户定义的配置文件定义,并封装不同的数据集。这些数据集中的每一个还可以包括一些用户定义的静态web文件(HTML,JPG,CSS等)。 每个servlet实例的静态资源都存储在webapp文件夹之外(以避免在重新部署时删除)​​,并且每个servlet实例都有一个单独的文件夹层次结构。

在监听器contextInitialized方法中,我正在使用 javax.servlet.ServletContext.addServlet 添加我的每个servlet实例,以及 javax.servlet.ServletRegistration.Dynamic.addMapping 添加此servlet的URL映射。

我想为外部文件夹中的静态内容添加其他映射。 在Tomcat 7中,我扩展了org.apache.catalina.servlets.DefaultServlet 将relativePath更改为我的新文档根目录,但此类 在Tomcat 8 0中无效 - ClassNotFoundException(org.apache.naming.resources.FileDirContext)。

Tomcat 8有一个新的“资源”框架,应该让这更加直截了当。

我的问题是 - 如何在不编辑web.xml的情况下动态地(在我的侦听器内的Web应用程序启动时)向我的上下文添加PostResources元素?

在我的听众中,我应该能够做到这样的事情:

WebResourceRoot root = new StandardRoot(context);
root.createWebResourceSet(WebResourceRoot.ResourceSetType.POST, 
    "/my/url", "my/filesystem/path", null, "/");

但我无法弄清楚如何获取所需的上下文(org.apache.catalina.Context),这是与侦听器contextInitialized方法中ServletContextEvent提供的类似命名的javax.servlet.ServletContext完全不同的类型。 / p>

有什么建议吗? 感谢。

1 个答案:

答案 0 :(得分:0)

我想我已经使用MBeanServer找到了它。 这似乎是一种迂回的方法 - 有没有办法从ServletContext获取StandardRoot或StandardContext对象?

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.servlet.ServletContext;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.Container;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.WebResourceRoot;

...

private void addPostResources(ServletContext servletContext)
    throws Exception /* just for debugging */ {

    MBeanServer mbs = MBeanServerFactory.findMBeanServer(null).get(0);
    ObjectName name = new ObjectName("Catalina","type","Server");
    Server server = (Server)mbs.getAttribute(name, "managedResource");
    Service service = server.findService("Catalina");
    StandardEngine engine = service.getContainer();
    Container hostContainer = engine.findChild(engine.getDefaultHost());

    StandardContext standardContext = (StandardContext)hostContainer.findChild(servletContext.getContextPath());

    WebResourceRoot root = standardContext.getResources();
    root.createWebResourceSet(WebResourceRoot.ResourceSetType.POST, 
        "/my/url", "my/filesystem/path", null, "/");
}