Используя 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

Другие вопросы по тегам