如何使用default-servlet-handler

时间:2011-11-05 20:54:07

标签: java spring spring-mvc

我想配置Spring MVC来提供与静态文件混合的动态文件,例如(URL => File):

/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时,只有动态的东西才有效。但是我想要同时使用这个,而这正是这个默认的servlet处理程序应该做什么,不是吗?这里的错误在哪里?

3 个答案:

答案 0 :(得分:4)

我有类似的问题,没有任何请求被映射到Spring控制器: 我发现我在spring config xml中错过了这个:

<mvc:annotation-driven/>

看来,这是必要的。从文档中可以看出:

Configures the annotation-driven Spring MVC Controller programming model

我还将让DefaultServlet处理静态内容请求。

所以你的spring配置应该是这样的:

<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 :(得分:1)

您需要定义两个重要配置

<mvc:annotation-driven/>

<mvc:default-servlet-handler />将启用您的默认基础架构bean,其中xmlns:mvc="http://www.springframework.org/schema/mvc"将通过转发到Servlet容器的默认Servlet来配置处理静态资源的处理程序。

也不要忘记mvc名称空间,即<?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>

我的完整配置文件(使用TilesViewResolver)如下所示

HandlerMapping

此外,如果您有多个includer.rb考虑订购它们。对于未明确提供订单的一个,Spring会以最低优先级对其进行处理。

答案 2 :(得分:0)

我认为您从ViewController返回的视图名称无效。我希望request.getServletPath()为所有URL返回一个空字符串,因为servlet的路径可能是/,Java文档说getServletPath()返回该路径的空字符串。因此,FreeMarker视图解析器可能忽略了视图名称,因为它不知道要显示什么。

然而,使用带有@RequestMapping的控制器类可能不是完成此任务的理想方式。 Spring包含ContentNegotiatingViewResolver,可根据内容类型自动确定正确的视图。 This overview of ContentNegotiatingViewResolver解释了如何设置它。