Используя Spring, сопоставление с root в web.xml, статические ресурсы не найдены - PullRequest
29 голосов
/ 25 января 2010

Что я пытаюсь сделать, это сопоставить запросы с корнем сервлета (правильная терминология?). Я нахожусь в точке, где 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 ПРЕДУПРЕЖДЕНИЕ [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 ПРЕДУПРЕЖДЕНИЕ [http-8080-5] servlet.DispatcherServlet (DispatcherServlet.java:962) - нет сопоставления найдено для HTTP-запроса с URI [/springapp/static/css/offers.css] в DispatcherServlet с именем «springapp» 2010-01-24 17: 25: 01,778 ВНИМАНИЕ [http-8080-3] servlet.DispatcherServlet (DispatcherServlet.java:962) - Не найдено сопоставление для HTTP-запроса с URI [/springapp/static/css/scrollable-buttons.css] в DispatcherServlet с именем 'springapp'

Собираюсь http://localhost:8080/springapp/shop работает нормально, но CSS и изображения отсутствуют.

Я думаю, что использование Tiles как-то усложняет ситуацию, но я не хочу от этого избавляться. Мне интересно, нужно ли мне как-то настраивать разрешение моего вида? просто не настолько опытный в этом.

Ответы [ 4 ]

61 голосов
/ 25 января 2010

Проблема в том, что запросы на статическое содержимое отправляются на 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>

Spring config:

<!-- Handles GET requests for /resources/** by efficiently serving static content 
    in the ${webappRoot}/resources dir --> 
<mvc:resources mapping="/resources/**" location="/resources/" /> 

См. Также Упрощение MVC весной 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>
5 голосов
/ 04 сентября 2012

Кто-нибудь рассматривал возможность использования этого:

<!-- 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#mvc-default-servlet-handler

4 голосов
/ 21 апреля 2010

В качестве альтернативы предлагаемому номеру решения (2, сервлет по умолчанию, который ведет себя по-разному от контейнера сервлета к контейнеру сервлета), я бы рекомендовал взглянуть на ресурсный сервлет (org.springframework.js.resource.ResourceServlet) из Проект Spring Webflow.

Для получения более подробной информации смотрите Как обрабатывать статический контент в Spring MVC?

1 голос
/ 09 июля 2012

У меня та же проблема, но вместо 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...