Оберните сервлет по умолчанию, но переопределите путь веб-приложения по умолчанию

У меня есть папка со статическим html, imgs, flash-контентом, который находится вне папки веб-приложения. Прямо сейчас я использую символическую ссылку, чтобы сопоставить эту папку с каталогом моего веб-приложения. У меня проблема в том, что когда я отменяю развертывание своего приложения, оно переходит по символической ссылке и удаляет все эти файлы.

Одно из решений, которые я пытаюсь реализовать, — это специальный сервлет, который является оболочкой для сервлета по умолчанию, но использует другой относительный путь. У меня возникли проблемы с поиском того, как обернуть сервлет по умолчанию таким образом, чтобы переопределить путь сервлета по умолчанию.

Вот с чем я работаю:

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);
}

person Ruggs    schedule 25.09.2009    source источник


Ответы (6)


Вы можете либо написать свой собственный сервлет для обслуживания статического контента (что не так сложно), либо попытаться расширить, а не обернуть DefaultServlet. В любом случае, ваш результирующий сервлет будет настроен вместо значения по умолчанию в вашем web.xml (используя "по умолчанию" в качестве имени сервлета).

Тем не менее, DefaultServlet будет обслуживать только статический контент из контекста вашего веб-приложения; чтобы изменить это, вам нужно создать/привязать к JNDI свой собственный экземпляр ProxyDirContext, указывающий на внешнюю папку, и я не уверен, сработает ли это; процесс его настройки достаточно сложен.

Попытка переопределить путь сервлета ни к чему не приведет.

person ChssPly76    schedule 25.09.2009

Вы можете переопределить DefaultServlet своей собственной реализацией. Вы можете прекрасно разделить его на подклассы, это открытый класс. Здесь представлены функциональные спецификации DefaultServlet, вы нужно его придерживаться.

С другой стороны, вы можете игнорировать DefaultServlet и найти собственное решение, пример можно найти здесь.

person BalusC    schedule 02.11.2009

У нас есть аналогичная проблема: нам нужно разделить некоторые файлы, созданные CMS, между несколькими приложениями. Symlink — это самый простой способ сделать это, если вы не используете Windows.

Настраиваем 2 аккаунта для CMS и Tomcat. Файлы доступны только для чтения Tomcat, поэтому он не может их удалить.

Вы также можете написать небольшое расширение Tomcat, чтобы оно могло искать файлы в нескольких местах. См. этот веб-сайт,

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

Ваш текущий подход не будет работать. Tomcat должен загрузить все ресурсы в кэш при развертывании, чтобы он был доступен. Слишком поздно что-то менять в обработке запросов. Это расширение позволяет Tomcat загружать ресурсы из нескольких каталогов. Недостатком этого подхода является то, что вам нужно поместить небольшой JAR в файл server/lib.

person ZZ Coder    schedule 26.09.2009
comment
В итоге я решил просто создать свой собственный серввет, который привязан к определенному пути. Я использую символические ссылки, поскольку файлы совместно используются несколькими узлами приложений, но должны быть доступны для записи. Это, конечно, не идеальное решение, но лучшее с учетом требований. - person Ruggs; 26.09.2009

Это не очень хорошая идея.

Веб-контейнеры или серверы приложений можно развернуть за веб-серверами, или вы можете просто использовать веб-сервер в сочетании с вашим контейнером. Просто поместите туда свои статические файлы и ссылайтесь на них по абсолютному пути.

На самом деле нет необходимости в таком хаке (извините, но это то, что есть).

Либо так, либо просто разверните их с помощью веб-приложения.

person cletus    schedule 25.09.2009
comment
К сожалению, контент должен быть защищен защитным фильтром. Мы уже используем apache httpd для большей части статического контента, но его папка особенная. Я согласен, что это взлом. - person Ruggs; 25.09.2009

Вы можете перейти на другой путь в контексте вашего веб-приложения. Вот пример, который выполняет дифференциальное обслуживание в зависимости от того, поддерживает ли пользовательский агент клиента 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», несмотря на то, что мы используем начальную косую черту, являются подкаталогами обычного контекста веб-приложения. С помощью этого метода невозможно выйти за пределы каталога контекста.

person Robert Tupelo-Schneck    schedule 13.10.2017

У меня есть собственный сервлет с открытым исходным кодом, который обслуживает файлы по произвольному базовому пути. Кроме того, он поддерживает просмотр файлов внутри вложенных сжатых архивов.

Он доступен здесь: https://bitbucket.org/teslamotors/zip-listing/overview

person kostmo    schedule 09.02.2014
comment
Я так понимаю, у вас нет доступа к этому репозиторию. - person Robert Mikes; 15.02.2017