简体   繁体   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

I perform refactoring and split controller into 2 controllers with: 我执行重构并将控制器拆分为2个控制器:

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

in first controller and: 在第一个控制器和:

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

in second controller so these annotations lie in different files. 在第二个控制器中,所以这些注释位于不同的文件中。 When I build and use project all is fine (I put input HTML tag in my forms with different names: first and second ). 当我构建和使用项目时,一切都很好(我在表单中输入了不同名称的输入 HTML标记: 第一个第二个 )。

But when I try to run JUnit controller test: 但是当我尝试运行JUnit控制器测试时:

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

I get trace: 我得到了痕迹:

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)

When I comment out this: 当我发表评论时:

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

in second controller individual test for first controller successfully completed. 在第二个控制器单独测试第一个控制器成功完成。

To resolve this issue I may use different URLs ( value in @RequestMapping ) but I don't understand why request mapping resolved for params in my production build of application and fail with SpringJUnit4ClassRunner . 要解决此问题,我可能会使用不同的URL( @RequestMapping中的 ),但我不明白为什么请求映射在我的应用程序的生成版本中解析为params并且使用SpringJUnit4ClassRunner失败。

Any help welcome! 欢迎任何帮助!

PS . PS I use Spring 3.2. 我使用Spring 3.2。

PPS . PPS I found mostly same issue Can I have the same mapping value with different param in a different Spring controller? 我发现大多数相同的问题我可以在不同的Spring控制器中使用不同的param具有相同的映射值吗? but according to answers my production build also must fail?! 但根据答案,我的生产构建也必须失败?! But I run production build successfully!! 但是我成功运行了生产!

Also refer to: 另请参阅:

*PPS . * PPS

I check official docs for 3.2: 我检查3.2的官方文档:

http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params%28%29 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.

So seems I perform illegal coding practice... 所以我似乎在进行非法编码练习......

This is what I understand when reading the official doc quoted in your question : 这是我在阅读您的问题中引用的官方文档时所理解的:

In a Servlet environment, parameter mappings are considered as restrictions that are enforced at the type level. 在Servlet环境中,参数映射被视为在类型级别强制执行的限制。 The primary path mapping (ie the specified URI value) still has to uniquely identify the target handler within the class , with parameter mappings simply expressing preconditions for invoking the handler. 主路径映射(即,指定的URI值)仍具有唯一地标识类内的目标的处理程序,与参数映射简单地表达用于调用处理程序的先决条件。

I added the words " within the class ". 我添加了“ 在课堂内 ”的字样。

And please note the enforced at type level . 请注意在类型级别强制执行 As I understand, it means that : in a servlet env. 据我所知,它意味着:在servlet环境中。 declaring the params at method level is quite the same as declaring the params at type level (at least if you only have only one method in your class). 在方法层次上声明params为完全一样的类型层次上声明PARAMS(至少如果你仅仅只有一个在你的类中的方法)。

Finally, if you take care to this sentence ( same source ): 最后,如果你注意这句话( 同一来源 ):

When used at the type level, all method-level mappings inherit this parameter restriction (ie the type-level restriction gets checked before the handler method is even resolved). 在类型级别使用时,所有方法级别映射都继承此参数限制(即在处理器方法甚至解析之前检查类型级别限制)。

I think all of this summarize why your are not doing illegal coding . 我想所有这些都总结了为什么你不进行非法编码

Regarding unit tests: 关于单元测试:

What is also important here are the words " In a Servlet environment . Obviously, when running unit tests : your not in a Servlet environment and that's probably why it is failing. 这里同样重要的是“ 在Servlet环境中 。显然,在运行单元测试时:您不在Servlet环境中 ,这可能是它失败的原因。

My neighbour colleague help me with debugging issue. 我的邻居同事帮我调试问题。

We compare production and test environment and found difference in context XML configuration. 我们比较生产和测试环境,发现上下文XML配置的差异。

Previous test configuration which fail: 以前的测试配置失败:

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

New and working test context configuration: 新的和工作的测试上下文配置:

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

Different spring classes use different mapping schema. 不同的spring类使用不同的映射模式。 Old uses per classes, newer uses per methods!! 每个类的旧用法,每种方法更新用途!!

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

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