对于没有 XML 的 Spring MVC 中的双调度程序配置,URL 映射无法按预期工作

Posted

技术标签:

【中文标题】对于没有 XML 的 Spring MVC 中的双调度程序配置,URL 映射无法按预期工作【英文标题】:URL Mapping is not working as expected for dual dispatcher config in Spring MVC with No XML 【发布时间】:2014-07-28 13:34:47 【问题描述】:

我是 Spring MVC 的新手,并尝试在我的示例程序中使用 Dual Dispatchers 制作基于 No XML Pure Annotation 的 Spring MVC 配置。然而,URL 映射并没有按照预期的方式工作。

首先让我解释一下我的示例程序做了什么。我的示例程序有两个部分 -公共 URL 部分 --> appName/ *.pub安全 URL 部分 --> appName/ *.sec

这两个部分都配置为使用 2 个不同的调度程序来解决视图的分辨率,这些调度程序在 Application Initializer 中配置如下:

public class springMVCwithHibernateMavenInitializer implements
    WebApplicationInitializer 

@Override
public void onStartup(ServletContext servletContext)
        throws ServletException 

    // Create the Spring application context
    String[] configLocations =  "test.springMVC.config","test.springMVC.controller" ;

    AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
    appContext.refresh();
    appContext.setConfigLocations(configLocations);
    appContext.register(AppConfig.class);

    // Manage the lifecycle of the application context
    servletContext.addListener(new ContextLoaderListener(appContext));

    /**/
    // Create the Public Dispatcher Servlet context
    AnnotationConfigWebApplicationContext publicWebMVCContext = new AnnotationConfigWebApplicationContext();
    publicWebMVCContext.register(PublicWebMVCConfig.class);

    // Register the Public Dispatcher Servlet
    ServletRegistration.Dynamic publicDispatcher = servletContext.addServlet("public-dispatcher", new DispatcherServlet(publicWebMVCContext));
    publicDispatcher.addMapping("*.pub");
    publicDispatcher.setLoadOnStartup(1);

    /**/
    // Create the Secure Dispatcher Servlet context
    AnnotationConfigWebApplicationContext secureWebMVCContext = new AnnotationConfigWebApplicationContext();
    secureWebMVCContext.register(SecureWebMVCConfig.class);

    // Register the Secure Dispatcher Servlet
    ServletRegistration.Dynamic secureDispatcher = servletContext.addServlet("secure-dispatcher", new DispatcherServlet(secureWebMVCContext));
    secureDispatcher.addMapping("*.sec");
    secureDispatcher.setLoadOnStartup(1);
    

PublicWebMVCConfig.java --> 将以 *.pub 结尾的 url 映射到物理路径 WEB-INF/jsp/public/*.jsp

@Configuration
@ComponentScan( "test.springMVC.config", "test.springMVC.controller" )
@EnableWebMvc
public class PublicWebMVCConfig extends WebMvcConfigurerAdapter 

private final String publicURIPrefix = "/jsp/public/";
private final String uriSuffix = ".jsp";

@Bean(name = "publicViewResolver")
public ViewResolver publicViewResolver() 

    InternalResourceViewResolver publicResolver = new InternalResourceViewResolver();
    publicResolver.setPrefix(publicURIPrefix);
    publicResolver.setSuffix(uriSuffix);

    return publicResolver;

  

SecureWebMVCConfig.java --> 将以 *.sec 结尾的 url 映射到物理路径 WEB-INF/jsp/secure/*.jsp [此处未包含代码]

这段代码出现的问题是,当我使用路径映射*.pub 调用url 时,它以某种方式使用secureDispatcher 而不是publicDispatcher,而路径*.sec 的url 使用publicDispatcher不应该是这样的。

当我为两个调度程序反转 springMVCwithHibernateMavenInitializer 类中的映射时,问题得到了解决,但这不是解决方案,我无法弄清楚为什么会发生这种情况。

请帮我解决这个问题,如果你能解释这个问题的原因,你也很好。我在谷歌上找不到具有多调度程序配置的基于注释的 Spring MVC 程序的相关参考。任何帮助表示赞赏。

您可以下载此示例程序here 的WAR 文件,以便重现该问题。顺便程序使用Spring v4.0.5,部署在Tomcat v7.0.25上。

【问题讨论】:

你怎么知道哪个Servlet被使用了?您能否举例说明您向其发送请求的 URL 以及结果是什么? 配置使得publicDispatcher 应该在PublicWebMVCConfig 中使用解析器,而secureDispatcher 应该在SecureWebMVCConfig 中使用解析器。 URL 示例:http://localhost:8080/springMVCMavenNoXML/login.pub 导致错误:请求的资源 (/springMVCMavenNoXML/jsp/secure/login.jsp) 不可用。它应该重定向到jsp/public/login.jsp。相反,它会重定向到 jsp/secure/login.jsp,这只有在使用为 secureDispatcher 配置的视图解析器时才会发生。 【参考方案1】:

@Configuration 包中的两个 @Configuration 类中,您已指定

 @ComponentScan( "test.springMVC.config", "test.springMVC.controller" )

所以每个@Configuration 类都会扫描并初始化那些声明的包中的组件b​​ean。其中一个bean 将是另一个 @Configuration 类的实例。 @Configuration 的特殊之处在于 Spring 将初始化在其注释类中声明的 bean。

在这种情况下,您的公共配置将创建两个 ViewResolver bean。碰巧它首先注册了安全的,这就是将要使用的。

您可以简单地从每个@Configuration 类的@ComponentScan 中删除test.springMVC.config 包来完成这项工作。

【讨论】:

@rockstar89 对。因此,当加载 PublicWebMVCConfigAnnotationConfigWebApplicationContext 对其进行初始化时,它会扫描 test.springMVC.config 包并初始化 SecureWebMVCConfig bean,该 bean 将初始化其 ViewResolver bean。 (反之亦然。)

以上是关于对于没有 XML 的 Spring MVC 中的双调度程序配置,URL 映射无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC 上的文件 .xml 中的错误

idea中web-inf下没有spring-mvc.xml

Spring 4 mvc REST XML 和 JSON 响应

错误:没有找到带有 URI spring mvc 且没有 xml 的 HTTP 请求的映射

Spring MVC中,applicationContext.xml [ServletName]-servlet.xml配置文件在web.xml中的配置详解...

了解 Spring MVC 中的上下文