Как использовать default-servlet-handler - PullRequest
7 голосов
/ 06 ноября 2011

Я хочу настроить Spring MVC для обслуживания динамических файлов, смешанных со статическими файлами, например (URL => Файл):

/iAmDynamic.html   => /WEB-INF/views/iAmDynamic.html.ftl
/iAmAlsoDynamic.js => /WEB-INF/views/iAmAlsoDynamic.js.ftl
/iAmStatiHtml      => /iAmStatic.html

DispatchServlet сопоставлен с /, конфигурация MVC на основе аннотаций включена, и у меня есть контроллер вида, подобный этому (упрощенный):

@Controller
public class ViewController
{
    @RequestMapping("*.html")
    public String handleHtml(final HttpServletRequest request)
    {
         return request.getServletPath();
    }

    @RequestMapping("*.js")
    public String handleJavaScript(final HttpServletRequest request)
    {
        return request.getServletPath();
    }
}

Конфигурация Spring выглядит следующим образом:

<context:component-scan base-package="myPackage" />

<mvc:default-servlet-handler />

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="templateLoaderPath" value="/WEB-INF/views/" />
</bean>

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
  <property name="cache" value="true" />
  <property name="prefix" value="" />
  <property name="suffix" value=".ftl" />
</bean>

К сожалению, это не работает. Когда этот <mvc:default-servlet-handler /> активен, я могу получить доступ только к файлу iAmStatic.html. Когда я отключаю default-servlet-handler, тогда работают только динамические вещи. Но я хочу и то и другое одновременно, и это именно то, что должен делать этот обработчик по умолчанию, или нет? Где здесь ошибка?

Ответы [ 3 ]

4 голосов
/ 14 февраля 2013

У меня была похожая проблема, ни один из запросов не был сопоставлен с Spring Controllers: я обнаружил, что мне не хватало этого в весеннем конфиге xml:

<mvc:annotation-driven/>

Кажется, это необходимо.Из документации, цель сделать это:

Configures the annotation-driven Spring MVC Controller programming model

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

Таким образом, ваш весенний конфиг должен выглядеть следующим образом:

<context:component-scan base-package="myPackage" />
<!-- Define location and mapping of static content -->
<mvc:resources location="/static/" mapping="/static/**"/>

<mvc:default-servlet-handler />
<mvc:annotation-driven/>
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  <property name="templateLoaderPath" value="/WEB-INF/views/" />
</bean>

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
  <property name="cache" value="true" />
  <property name="prefix" value="" />
  <property name="suffix" value=".ftl" />
</bean>

Надеюсь, это поможет!

1 голос
/ 09 сентября 2015

Вам необходимо определить две важные конфигурации

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

<mvc:annotation-driven/> включит компоненты инфраструктуры по умолчанию, где <mvc:default-servlet-handler /> настроит обработчик для обслуживания статических ресурсов путем пересылки сервлету по умолчанию контейнера сервлета.

Также не забудьте про пространство имен mvc, т.е. xmlns:mvc="http://www.springframework.org/schema/mvc"

Мой полный файл конфигурации (с использованием TilesViewResolver) выглядит следующим образом:

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

    <mvc:annotation-driven/>

    <!-- 
      Configures a handler for serving static resources by forwarding to the 
      Servlet container's default Servlet. 
    -->
    <mvc:default-servlet-handler />

    <mvc:view-controller path="/" view-name="welcome"/>
    <mvc:view-controller path="/home" view-name="welcome"/>

    <bean class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles.xml</value>
            </list>
        </property>
    </bean> 

    <bean class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
        <property name="order" value="1"/>
    </bean> 

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="order" value="2"/>
        <property name="prefix" value="/WEB-INF/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

Также, если у вас несколькоHandlerMapping рассматривает возможность их заказа.Для того, для которого вы не указали порядок явно, Spring рассматривает его с наименьшим приоритетом.

0 голосов
/ 06 ноября 2011

Я думаю, что имя представления, которое вы возвращаете из ViewController, недопустимо. Я ожидаю, что request.getServletPath() возвращает пустую строку для всех URL, потому что путь к вашему сервлету, вероятно, равен /, а в документации Java сказано, что getServletPath() возвращает пустую строку для этого пути. Поэтому распознаватель представлений FreeMarker, вероятно, игнорирует имя представления, поскольку не знает, что показать.

Однако использование класса контроллера с @RequestMapping, вероятно, в любом случае не идеальный способ выполнить эту задачу. Spring включает ContentNegotiatingViewResolver , который автоматически определяет правильное представление в зависимости от типа содержимого. Этот обзор ContentNegotiatingViewResolver объясняет, как его настроить.

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