有什么方法可以使Tomcat WebdavServlet
服务于外部目录,而不是仅服务于webapp上下文资源?我了解到WebdavServlet
扩展了DefaultServlet
。我尝试扩展WebdavServlet
,并覆盖resources
ProxyDirContext
,但这种方式无法正常工作。它返回null
,并且不能脱离webapp上下文。我有这个结构。
链接:http://localhost:8080/my-web-context
部署:/usr/local/apache-tomcat-7.0.56/webapps/my-web-context
WebDAV资源:/data
如果仅配置WebdavServlet
,则只能浏览和访问http://localhost:8080/my-web-context/webdav
Web应用程序资源的my-web-context
。
或者,也许可以配置除我的Webapp上下文资源以外的其他资源(即/data
)到WebdavServlet/DefaultServlet
中?如果是这样,这也可以解决我的用例。但是符号链接不是首选。我知道这种配置可以在Apache httpd webdav模块中轻松完成,但是我希望在Tomcat上进行配置,以便于Java Webapp轻松集成。
最佳答案
终于,我开始工作了。空问题是因为resources.getEnvironment()
返回在DefaultServlet
初始化的空白环境对象。并且ProxyDirContext
构造函数具有contextName = env.get(CONTEXT); int i = contextName.indexOf('#');
,将抛出null。无论如何,这是工作代码。
首先,如果配置了外部WebdavServlet
,它将扩展Tomcat resources
并覆盖servlet init()
内部的repoPath
。
public class MyWebdavServlet extends WebdavServlet {
@Override
public void init() throws ServletException {
super.init();
String repoPath = getServletConfig().getInitParameter("repoPath");
if (Strings.isNullOrEmpty(repoPath)) {
return;
}
FileDirContext fileDirContext = new FileDirContext();
fileDirContext.setDocBase(repoPath);
//Hashtable<String, String> env = resources.getEnvironment(); won't work, throw null when we construct ProxyDirContext!
//setup environment object manually
Hashtable<String, String> env = new Hashtable<>();
env.put(ProxyDirContext.HOST, resources.getHostName());
env.put(ProxyDirContext.CONTEXT, resources.getContextPath());
resources = new ProxyDirContext(env, fileDirContext);
}
//do more override...
}
web.xml
中的servlet映射将是:<servlet>
<servlet-name>webdav</servlet-name>
<servlet-class>com.sankholin.webdav.MyWebdavServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>repoPath</param-name>
<param-value>/data</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>webdav</servlet-name>
<url-pattern>/webdav/*</url-pattern>
</servlet-mapping>