【问题标题】:How do I implicitly map folder views without breaking resource mappings?如何在不破坏资源映射的情况下隐式映射文件夹视图?
【发布时间】:2013-05-16 04:01:35
【问题描述】:

我正在尝试为一个可以处理以下情况的 Spring Web 应用程序设置一个非常简单的基本配置:

  • 将资源根请求映射到/index,例如/ 映射到/index/resource/ 映射到/resource/index
  • /static/** 映射到/static/(这是资源视图 - css、js、图像)
  • 使用控制器映射处理一些特定的请求路径
  • 将所有其他请求映射到基于 url 的视图,例如 /resource/page 映射到 /WEB-INF/views/resource/page.jsp

在我目前的配置中,我拥有的是:

<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<mvc:resources mapping="/static/**" location="/static/"/>
<mvc:view-controller path="/" view-name="index"/>

适用于静态资源和根请求 (/),但不适用于基于资源的根请求 (/resource/)。在尝试处理所有其他请求时 (**/),我中断了对静态资源的处理。

<mvc:view-controller path="**/*" />

有没有办法同时做所有这些事情?它不需要是纯 xml 的解决方案,我可以使用代码配置或混合解决方案。

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    我通过实现自己的ControllerConfig 设法找到了解决方案。

    view-servlet.xml

    <mvc:resources mapping="/static/**" location="/static/"/>
    <context:component-scan base-package="com.example.web.view"/>
    

    com.example.web.view.ViewConfig

    @Configuration
    public class ViewConfig {
    
        @Bean
        public ViewResolver viewResolver() {
            InternalResourceViewResolver vr = new InternalResourceViewResolver();
            vr.setPrefix("/WEB-INF/views/");
            vr.setSuffix(".jsp");
            return vr;
        }
    
        @Bean RequestMappingHandlerMapping requestMappingHandlerMapping(){
            return new RequestMappingHandlerMapping();
        }
    
        @Bean RequestMappingHandlerAdapter requestMappingHandlerAdapter(){
            RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
            adapter.setOrder(2); //process after mvc:resources
            return adapter;
        }
    }
    

    com.example.web.view.ViewController

    @Controller
    public class ViewController {
    
        @RequestMapping(value = "**/")
        public String all(HttpServletRequest request) {     
            String path = request.getRequestURI().replace(request.getContextPath(),"");
            return path.endsWith("/") ? path +"index" : path;
        }
    
    }
    

    神奇之处在于在ViewConfig 中设置适配器上的订单值。 Spring 创建一个默认映射处理程序,将组件扫描找到的所有RequestMappings 添加到该处理程序中。我的初始设置失败的原因是这个处理程序的顺序是在mvc:resources 注册的那个之前匹配。创建我自己的适配器并将其设置为在mvc:resources 之后处理它允许两者都工作。

    有关这方面的信息可以在 spring 文档19.9.1 Setting up the dispatcher for annotation support 中找到。

    当然ViewConfig也可以纯xml实现:

    <mvc:resources mapping="/static/**" location="/static/"/>
    
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="order" value="2"/>
    </bean>
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
    <context:component-scan base-package="com.example.web.view"/>
    

    更新:DefaultAnnotationHandlerMappingAnnotationMethodHandlerAdapter 更改为 RequestMappingHandlerMappingRequestMappingHandlerAdapter,以反映 Spring 3.1.x 及更高版本中所做的更改。

    【讨论】:

      猜你喜欢
      • 2011-10-30
      • 2012-07-16
      • 1970-01-01
      • 2014-06-06
      • 1970-01-01
      • 2011-12-02
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      相关资源
      最近更新 更多