Используя Spring, сопоставление с root в web.xml, статические ресурсы не найдены
Я пытаюсь сопоставить запросы к корню сервлета (правильная терминология?). Я нахожусь в точке, где URL-адреса сопоставлены для правильного просмотра, но все статическое содержимое - css, javascript, images - которое является частью страницы, не может быть найдено.
Так что в моем web.xml мой тег сервлета выглядит так
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Мой контроллер выглядит примерно так:
@RequestMapping("/shop")
public class TheShopController extends MyBaseController {
public static String VIEW = "Tile.Shop";
@Override
@RequestMapping(method = RequestMethod.GET)
protected ModelAndView processRequest(HttpServletRequest req, HttpServletResponse resp) {
ModelAndView mav = new ModelAndView(VIEW);
return mav;
}
}
MyBaseController очень прост. Это выглядит так:
public abstract class MyBaseController extends AbstractController {
protected Logger log = Logger.getLogger(getClass());
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp)
throws Exception {
ModelAndView mav = processRequest(req, resp);
return mav;
}
protected abstract ModelAndView processRequest(HttpServletRequest req, HttpServletResponse resp);
}
Я использую плитки в моем слое просмотра. Моя конфигурация выглядит следующим образом:
/WEB-INF/tiles-defs.xml
Как я уже упоминал, представления найдены, но статические ресурсы, которые являются портом страницы, не могут быть найдены. Вот несколько типичных выходов из системы:
2010-01-24 17: 25: 01,777 DEBUG [http-8080-7] servlet.DispatcherServlet (DispatcherServlet.java:690) - DispatcherServlet с именем 'springapp' обрабатывает GET-запрос для [/springapp/static/css/account.css] 2010-01-24 17:25:01,778 WARN [http-8080-4] servlet.DispatcherServlet (DispatcherServlet.java:962) - не найдено сопоставление для HTTP-запроса с URI [/springapp/static/css/shop.css] в DispatcherServlet с именем "springapp" 2010-01-24 17:25:01,778 DEBUG [http-8080-6] servlet.FrameworkServlet (FrameworkServlet.java:677) - успешно выполненный запрос 2010-01-24 17:25:01,778 WARN [http-8080-5] servlet.DispatcherServlet (DispatcherServlet.java:962) - не найдено сопоставление для HTTP-запроса с URI [/springapp/static/css/offers.css] в DispatcherServlet с именем "springapp" 2010-01-24 17:25:01,778 WARN [http-8080-3] servlet.DispatcherServlet (DispatcherServlet.java:962) - не найдено сопоставление для HTTP-запроса с URI [/springapp/static/css/scrollable-buttons.css] в DispatcherServlet с именем "SPRI ngapp"
Переход на http://localhost:8080/springapp/shop работает нормально, но CSS и изображения отсутствуют.
Я думаю, что использование Tiles каким-то образом усложняет ситуацию, но я не хочу от нее избавляться. Мне интересно, нужно ли мне каким-то образом настраивать разрешение моего представления, нужно каким-то образом подправить? Возможно, объединение преобразователей представления? Я просто не такой опыт в этом.
4 ответа
Проблема в том, что запросы на статическое содержимое отправляются на dispatcherServlet, потому что он отображается как <url-pattern>/</url-pattern>
, Это очень распространенная проблема в приложениях с URL-адресами "RESTful" (то есть без префикса в DispatcherServlet
отображение).
Есть несколько возможных способов решения этой проблемы:
Начиная с Spring 3.x предпочтительным способом доступа к статическим ресурсам является использование <mvc:resources>
: web.xml
:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Весенний конфиг:
<!-- Handles GET requests for /resources/** by efficiently serving static content
in the ${webappRoot}/resources dir -->
<mvc:resources mapping="/resources/**" location="/resources/" />
Смотрите также Упрощения MVC в Spring 3
1. Используйте фильтр перезаписи URL
Увидеть mvc-basic
пример здесь
2. Установите префикс для default
сервлет:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
То есть запрос на /static/images/image.png
вернет файл с именем /images/image.png
Однако этот способ несовместим в разных контейнерах сервлетов (не работает в Jetty), здесь можно найти обходные пути
3. Установите статические расширения контента для default
сервлет:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
4. Не используйте RESTful URL, используйте URL с префиксом:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
5. Не используйте RESTful URL, используйте URL с расширением:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Кто-нибудь рассматривал возможность использования этого:
<!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource requests to the container's default Servlet -->
<mvc:default-servlet-handler/>
Вот последние весенние документы: http://static.springsource.org/spring/docs/3.1.2.RELEASE/spring-framework-reference/htmlsingle/spring-framework-reference.html
В качестве альтернативы предлагаемому номеру решения (2, сервлет по умолчанию, который ведет себя по-разному от контейнера сервлета к контейнеру сервлета), я бы рекомендовал взглянуть на сервлет ресурсов (org.springframework.js.resource.ResourceServlet
) из проекта Spring Webflow.
Для получения более подробной информации, пожалуйста, взгляните на Как обрабатывать статический контент в Spring MVC?
У меня та же проблема, но вместо использования Spring я делаю mysefl небольшой фильтр, который перенаправляет root на мою стартовую страницу следующим образом:
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String pageName = req.getServletPath();
if(pageName.equals("/")) {
res.sendRedirect( req.getContextPath() + "/start" );
} else {
chain.doFilter(request, response);
}
Это может быть трюк, но похоже, что он отлично работает с небольшим кодом. Перейдите сюда для получения дополнительной информации о фильтре http://www.oracle.com/technetwork/java/filters-137243.html