Как получить доступ к статическим ресурсам при отображении сервлета глобального фронт-контроллера в / *

java servlets resources

111186 просмотра

18 ответа

Я отобразил диспетчер Spring MVC как сервлет глобального фронт-контроллера /*.

<servlet>       
  <servlet-name>home</servlet-name>         
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     
</servlet>  
<servlet-mapping>       
  <servlet-name>home</servlet-name>         
  <url-pattern>/*</url-pattern>     
</servlet-mapping>

Однако это сопоставление останавливает доступ к статическим файлам, таким как CSS, JS, изображения и т. Д., Которые находятся в /res/папке.

Как я могу получить к ним доступ в любом случае?

Автор: Rahul Garg Источник Размещён: 17.05.2019 02:34

Ответы (18)


12 плюса

Решение

Я столкнулся с этим также и никогда не находил отличного решения. Я закончил отображать свой сервлет на один уровень выше в иерархии URL:

<servlet-mapping>       
  <servlet-name>home</servlet-name>             
  <url-pattern>/app/*</url-pattern>     
</servlet-mapping>

И теперь все в базовом контексте (и в вашем каталоге / res) может обслуживаться вашим контейнером.

Автор: Gandalf Размещён: 15.05.2009 07:33

70 плюса

Сопоставьте сервлет контроллера с более конкретным url-patternаналогом /pages/*, поместите статический контент в определенную папку /staticи создайте Filterпрослушивание, /*которое прозрачно продолжает цепочку для любого статического контента и отправляет запросы сервлету контроллера для другого контента.

В двух словах:

<filter>
    <filter-name>filter</filter-name>
    <filter-class>com.example.Filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>controller</servlet-name>
    <servlet-class>com.example.Controller</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>controller</servlet-name>
    <url-pattern>/pages/*</url-pattern>
</servlet-mapping>

со следующим в фильтре doFilter():

HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());

if (path.startsWith("/static")) {
    chain.doFilter(request, response); // Goes to default servlet.
} else {
    request.getRequestDispatcher("/pages" + path).forward(request, response);
}

Нет, это не заканчивается /pagesв адресной строке браузера. Это полностью прозрачно. Вы можете при необходимости макияжа "/static"и / или фильтра."/pages"init-param

Автор: BalusC Размещён: 29.08.2010 04:27

43 плюса

С Spring 3.0.4.RELEASE и выше вы можете использовать

<mvc:resources mapping="/resources/**" location="/public-resources/"/>

Как видно из Spring Reference .

Автор: Joaquín L. Robles Размещён: 24.01.2011 07:10

19 плюса

Что вы делаете, это добавляете файл приветствия в ваш web.xml

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

А затем добавьте это в ваши сопоставления сервлетов, чтобы, когда кто-то переходил в корень вашего приложения, он отправлялся внутренне в index.html, а затем сопоставление внутренне отправляло их сервлету, которому вы сопоставили его.

<servlet-mapping>
    <servlet-name>MainActions</servlet-name>
    <url-pattern>/main</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>MainActions</servlet-name>
    <url-pattern>/index.html</url-pattern>
</servlet-mapping>

Конечный результат: Вы посещаете / Application, но вам представлен сервлет / Application / MainActions без прерывания любых других корневых запросов.

Возьми? Таким образом, ваше приложение все еще находится на дополнительном URL, но автоматически отображается, когда пользователь переходит в корень вашего сайта. Это позволяет вам /images/bob.img по-прежнему переходить в обычное место, но «/» - это ваше приложение.

Автор: casey Размещён: 17.08.2010 05:33

17 плюса

Если вы используете Tomcat, вы можете сопоставить ресурсы сервлету по умолчанию:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

и получить доступ к своим ресурсам с помощью URL http: // {context path} / static / res / ...

Также работает с Jetty, не уверен насчет других контейнеров сервлетов.

Автор: user112483 Размещён: 26.05.2009 10:03

16 плюса

Обслуживание статического контента с соответствующим суффиксом в нескольких определениях сопоставления сервлетов решило проблему безопасности, которая упоминается в одном из комментариев в одном из опубликованных ответов. Цитируется ниже:

Это была дыра в безопасности в Tomcat (таким образом доступны материалы WEB-INF и META-INF), и она была исправлена ​​в 7.0.4 (и будет также портирована на 5.x и 6.x). - BalusC 2 ноября 2010 года в 22:44

что мне очень помогло. И вот как я это решил:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>
Автор: GO' Размещён: 03.01.2012 07:11

9 плюса

Начиная с версии 3.0.4, вы должны быть в состоянии использовать mvc:resourcesв сочетании с тем, mvc:default-servlet-handlerкак описано в весенней документации, для достижения этой цели.

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-static-resources

Автор: digitaljoel Размещён: 02.11.2010 07:03

5 плюса

Кажется, причина конфликта заключается в том, что по умолчанию корень контекста "/" должен обрабатываться org.apache.catalina.servlets.DefaultServlet. Этот сервлет предназначен для обработки запросов на статические ресурсы.

Если вы решите исключить его с помощью своего собственного сервлета с целью обработки динамических запросов, этот сервлет верхнего уровня также должен выполнять любые задачи, выполняемые оригинальным обработчиком catalina «DefaultServlet».

Если вы читаете документы Tomcat, они упоминают, что True Apache (httpd) лучше, чем Apache Tomcat, для обработки статического контента, поскольку он специально создан для этого. Я предполагаю, что Tomcat по умолчанию использует org.apache.catalina.servlets.DefaultServlet для обработки статических запросов. Поскольку все это заключено в JVM, а Tomcat предназначен для использования в качестве контейнера Servlet / JSP, они, вероятно, не написали этот класс как супероптимизированный обработчик статического содержимого. Это здесь. Это делает работу. Достаточно хорошо.

Но это то, что обрабатывает статический контент, и он живет в "/". Так что, если вы положите туда что-нибудь еще, и эта штука не будет обрабатывать статические запросы, WHOOPS, туда уйдут ваши статические ресурсы.

Я искал один и тот же ответ, и ответ, который я получаю повсюду: «Если ты не хочешь, чтобы это делалось, не делай этого».

Короче говоря, ваша конфигурация заменяет обработчик статических ресурсов по умолчанию чем-то, что вообще не является обработчиком статических ресурсов. Вам нужно будет попробовать другую конфигурацию, чтобы получить результаты, которые вы ищете (как и я).

Автор: Bill Размещён: 15.12.2009 08:24

3 плюса

«Статические» файлы в App Engine не доступны напрямую вашему приложению. Вам нужно либо загрузить их дважды, либо обслуживать статические файлы самостоятельно, а не использовать статический обработчик.

Автор: Nick Johnson Размещён: 30.09.2009 01:21

2 плюса

Лучший способ справиться с этим - использовать переписывание URL-адресов. Таким образом, вы можете иметь чистые спокойные URL-адреса, а НЕ с какими-либо расширениями, например abc.com/welcom/register, а не abc.com/welcome/resister.html.

Я использую Tuckey URL, который довольно крутой.

Там есть инструкции по настройке вашего веб-приложения. Я настроил его с помощью моего веб-приложения Spring MVC. Конечно, все было хорошо, пока я не захотел использовать аннотации для валидации Spring 3, например @Emailили @Nullдля объектов домена.

Когда я добавляю Spring mvc директивы:

< mvc:annotation-driven  /> 
< mvc:default-servlet-handler />

.. это нарушает старый добрый код Tuckey. Видимо, < mvc:default-servlet-handler />заменяет Такки, который я до сих пор пытаюсь решить.

Автор: logixplayer Размещён: 18.09.2010 07:35

1 плюс

Добавьте папки, которые вы не хотите запускать в обработку сервлета, в <static-files>раздел файла appengine-web.xml.

Я только что сделал это и похоже, что все начинает работать нормально. Вот моя структура:

/

/pages/<.jsp файлы>

/ CSS

Я добавил «/ pages / **» и «/ css / **» в <static-files>раздел, и теперь я могу пересылать файл .jsp из doGet сервлета без создания бесконечного цикла.

Автор: MStodd Размещён: 28.08.2010 11:52

1 плюс

После безуспешной попытки применения фильтра (по какой-то причине он не вошел в функцию doFilter ()), я немного изменил настройки и нашел очень простое решение проблемы обслуживания корневого каталога:

Вместо того, чтобы использовать «/ *» в моем главном сервлете, я теперь слушаю только специальные языковые префиксы «EN», «EN / *», «DE», «DE / *»

Статический контент обслуживается сервлетом по умолчанию, а пустые корневые запросы отправляются в index.jsp, который вызывает мой основной сервлет с языком по умолчанию:

(другого содержимого на странице индекса нет.)

Автор: sebut Размещён: 19.12.2011 08:42

1 плюс

Я обнаружил, что с помощью

<mvc:default-servlet-handler />

весной у меня работает файл определения bean-компонента сервлета MVC. Он передает любой запрос, который не обрабатывается зарегистрированным контроллером MVC, на оригинальный обработчик контейнера по умолчанию, который должен служить ему в качестве статического содержимого. Просто убедитесь, что у вас нет зарегистрированного контроллера, который обрабатывает все, и он должен работать просто отлично. Не уверен, почему @logixplayer предлагает переписать URL; вы можете добиться того эффекта, который он ищет, просто адекватно используя Spring MVC.

Автор: Jules Размещён: 10.02.2014 09:59

0 плюса

Я бы порекомендовал по возможности использовать Фильтр вместо сервлета по умолчанию.

Другие две возможности:

Напишите FileServlet самостоятельно. Вы найдете множество примеров, он должен просто открыть файл по URL и записать его содержимое в выходной поток. Затем используйте его для обслуживания статического запроса файла.

Создайте класс FileServlet, используемый Google App Engine и службой вызовов (запрос, ответ) для этого FileServlet, когда вам нужно предоставить статический файл по заданному URL-адресу.

Вы можете сопоставить / res / * с YourFileServlet или любым другим, чтобы исключить его из обработки DispatcherServlets, или вызвать его непосредственно из DispatcherServlet.

И я должен спросить, что в документации Spring говорится об этом столкновении? Я никогда не использовал это.

Автор: alamar Размещён: 15.05.2009 06:27

0 плюса

Я нашел более простое решение с фиктивным индексным файлом.

Создайте сервлет (или используйте тот, который вы хотите ответить на «/»), который сопоставляется с «/index.html» (решения, упомянутые здесь, используют сопоставление через XML, я использовал версию 3.0 с аннотацией @WebServlet) Затем создайте статический (пустой) файл в корне статического содержимого с именем «index.html»

Я использовал Jetty, и произошло то, что сервер распознал файл вместо того, чтобы перечислить каталог, но когда его спросили о ресурсе, мой сервлет взял на себя управление. Все остальные статические материалы остались без изменений.

Автор: Matheus Borges Teixeira Размещён: 09.08.2014 07:24

0 плюса

В Embedded Jetty мне удалось добиться чего-то подобного, добавив сопоставление для каталога "css" в web.xml. Явно говорю ему использовать DefaultServlet:

<servlet>
  <servlet-name>DefaultServlet</servlet-name>
  <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>DefaultServlet</servlet-name>
  <url-pattern>/css/*</url-pattern>
</servlet-mapping>
Автор: QaZ Размещён: 15.12.2015 05:54

0 плюса

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:default-servlet-handler/>
</beans>

и если вы хотите использовать конфигурацию на основе аннотаций, используйте приведенный ниже код

@Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
Автор: Jekin Kalariya Размещён: 31.12.2015 11:13

0 плюса

Что касается Tomcat, многое зависит от конкретной версии. Была исправлена ​​ошибка https://bz.apache.org/bugzilla/show_bug.cgi?id=50026, которая означает, что (кроме '/') для сервлета по умолчанию ведет себя по-разному в Tomcat 6.0.29 (и ранее) по сравнению с более поздними версиями.

Автор: Mike Beaumont Размещён: 11.04.2019 03:23
Вопросы из категории :
32x32