繁体   English   中英

@RequestMapping与不同类中相同URL的“params”导致JUnit中的“IllegalStateException:无法映射处理程序”与SpringJUnit4ClassRunner

[英]@RequestMapping with “params” on same URL in different classes cause “IllegalStateException: Cannot map handler” in JUnit with SpringJUnit4ClassRunner

我执行重构并将控制器拆分为2个控制器:

@RequestMapping(value = "/graph.htm", method = RequestMethod.POST, params="first")

在第一个控制器和:

@RequestMapping(value = "/graph.htm", method = RequestMethod.POST, params="second")

在第二个控制器中,所以这些注释位于不同的文件中。 当我构建和使用项目时,一切都很好(我在表单中输入了不同名称的输入 HTML标记: 第一个第二个 )。

但是当我尝试运行JUnit控制器测试时:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:test-context.xml" })

我得到了痕迹:

Caused by: java.lang.IllegalStateException: Cannot map handler 'firstController'
  to URL path [/graph.htm]: There is already handler
  of type [class com.web.controller.SecondController] mapped.
    at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:294)
    at org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.registerHandler(AbstractUrlHandlerMapping.java:266)
    at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.detectHandlers(AbstractDetectingUrlHandlerMapping.java:82)
    at org.springframework.web.servlet.handler.AbstractDetectingUrlHandlerMapping.initApplicationContext(AbstractDetectingUrlHandlerMapping.java:58)
    at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:119)
    at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:72)
    at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:73)
    at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:117)
    at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:399)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1479)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)

当我发表评论时:

@RequestMapping(value = "/graph.htm", method = RequestMethod.POST, params="second")

在第二个控制器单独测试第一个控制器成功完成。

要解决此问题,我可能会使用不同的URL( @RequestMapping中的 ),但我不明白为什么请求映射在我的应用程序的生成版本中解析为params并且使用SpringJUnit4ClassRunner失败。

欢迎任何帮助!

PS 我使用Spring 3.2。

PPS 我发现大多数相同的问题我可以在不同的Spring控制器中使用不同的param具有相同的映射值吗? 但根据答案,我的生产构建也必须失败?! 但是我成功运行了生产!

另请参阅:

* PPS

我检查3.2的官方文档:

http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params%28%29

In a Servlet environment, parameter mappings are considered as restrictions
that are enforced at the type level. The primary path mapping (i.e. the
specified URI value) still has to uniquely identify the target handler, with
parameter mappings simply expressing preconditions for invoking the handler.

所以我似乎在进行非法编码练习......

这是我在阅读您的问题中引用的官方文档时所理解的:

在Servlet环境中,参数映射被视为在类型级别强制执行的限制。 主路径映射(即,指定的URI值)仍具有唯一地标识类内的目标的处理程序,与参数映射简单地表达用于调用处理程序的先决条件。

我添加了“ 在课堂内 ”的字样。

请注意在类型级别强制执行 据我所知,它意味着:在servlet环境中。 在方法层次上声明params为完全一样的类型层次上声明PARAMS(至少如果你仅仅只有一个在你的类中的方法)。

最后,如果你注意这句话( 同一来源 ):

在类型级别使用时,所有方法级别映射都继承此参数限制(即在处理器方法甚至解析之前检查类型级别限制)。

我想所有这些都总结了为什么你不进行非法编码

关于单元测试:

这里同样重要的是“ 在Servlet环境中 。显然,在运行单元测试时:您不在Servlet环境中 ,这可能是它失败的原因。

我的邻居同事帮我调试问题。

我们比较生产和测试环境,发现上下文XML配置的差异。

以前的测试配置失败:

<bean name="handlerMapping"
          class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
    <bean name="handlerAdapter"
          class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

新的和工作的测试上下文配置:

<bean name="handlerMapping"
          class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <bean name="handlerAdapter"
          class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

不同的spring类使用不同的映射模式。 每个类的旧用法,每种方法更新用途!!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM