包装默认servlet但覆盖默认的webapp路径

时间:2009-09-25 16:50:17

标签: java servlets

我有一个静态html,imgs,flash内容的文件夹,它们位于webapp文件夹之外。现在我正在使用符号链接将该文件夹映射到我的webapp目录。我遇到的问题是当我取消部署我的应用程序时,它遵循符号链接并删除所有这些文件。

我正在尝试实现的解决方案之一是一个特殊的servlet,它包装默认的servlet但使用不同的相对路径。我无法找到如何以覆盖默认servlet路径的方式包装默认servlet。

以下是我正在使用的内容:

public void doGet(final HttpServletRequest req, final HttpServletResponse resp)
    throws ServletException, IOException {
    final RequestDispatcher rd = getServletContext().getNamedDispatcher("default");
    final HttpServletRequest wrapped = new HttpServletRequestWrapper(req) {

        @Override
        public String getServletPath() {
            return "/usr/depot/repository";
        }
    };

    rd.forward(wrapped, resp);
}

6 个答案:

答案 0 :(得分:3)

您可以使用自己的实现覆盖DefaultServlet。你可以完美地将它子类化,它是一个公共类。 Here是DefaultServlet的功能规范,您需要遵守它。

另一方面,您可以忽略DefaultServlet并寻找自己的解决方案,可以找到一个示例here

答案 1 :(得分:2)

您可以编写自己的servlet以提供静态内容(这并不难)或尝试扩展而不是包装DefaultServlet。无论哪种方式,您生成的servlet都将在web.xml中配置为默认值(使用“default”作为servlet-name)。

也就是说,DefaultServlet只会在你的webapp上下文中提供静态内容;为了改变你必须创建/绑定到JNDI你自己的ProxyDirContext实例指向外部文件夹,我不知道这是否会起作用;它的配置过程非常复杂。

尝试覆盖servlet路径不会让你到任何地方。

答案 2 :(得分:1)

我们遇到类似的问题,我们需要在多个应用程序中共享CMS生成的一些文件。如果您不使用Windows,Symlink是最简单的方法。

我们为CMS和Tomcat设置了2个帐户。这些文件对Tomcat是只读的,因此无法删除它们。

您还可以编写一个小的Tomcat扩展,以便它可以在多个位置查找文件。请参阅此网站

http://blog.bazoud.com/post/2009/05/12/Multiples-docbases-avec-tomcat

您目前的做法不起作用。 Tomcat需要在部署时加载缓存中的所有资源才能使其可用。在请求处理中改变它为时已晚。此扩展允许Tomcat从多个目录加载资源。这种方法的缺点是你必须在server / lib中放一个小JAR。

答案 3 :(得分:0)

这不是一个好主意。

Web容器或应用程序服务器可以部署在Web服务器后面,也可以简单地将Web服务器与容器结合使用。只需将静态文件置于其下并通过绝对路径引用它们。

真的没有必要进行这种黑客攻击(对不起,但就是这样)。

或者只是使用Web应用程序部署它们。

答案 4 :(得分:0)

我开源了一个自定义servlet,它从任意基本路径提供文件。此外,它还支持嵌套压缩存档中的文件浏览。

可在此处找到:https://bitbucket.org/teslamotors/zip-listing/overview

答案 5 :(得分:0)

您可以在webapp上下文中更改为其他路径。这是一个根据客户端的User-Agent是否支持ES6来执行差异服务的示例:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    RequestDispatcher rd = getServletContext().getNamedDispatcher("default");
    HttpServletRequest wrapped = new HttpServletRequestWrapper(req) {
        @Override
        public String getServletPath() {
            String prefix = supportsES6(req) ? "/es6" : "/es5";
            String newPath =  prefix + req.getServletPath();
            if (newPath.endsWith("/")) newPath += "index.html";
            return newPath;
        }
    };
    rd.forward(wrapped, resp);
}

然而,“es5”和“es6”,即使我们使用初始斜杠,也是webapp普通上下文的子目录。使用此方法无法在上下文目录之外中断。