【问题标题】:Spring MVC 3 : Ambiguous mapping foundSpring MVC 3:发现不明确的映射
【发布时间】:2012-02-13 03:12:46
【问题描述】:

我正在使用 spring MVC 3.1 并测试不同的功能。我想验证以下来自@RequestMapping#value doc的声明

If you have a single default method (without explicit path mapping), then all requests without a more specific mapped method found will be dispatched to it. If you have multiple such default methods, then the method name will be taken into account for choosing between them

所以我创建了以下具有多个默认处理程序方法的控制器。

@Controller
@RequestMapping("/book")
public class BookController {

    @RequestMapping
    public @ResponseBody String greet() {
        return "Hi Book!";
    }

    @RequestMapping
    public @ResponseBody String meet() {
        return "Nice to meet you Book!";
    }
}

这是 Web 应用程序上下文配置

<beans ....>
<!-- Use @Component annotations for bean definitions -->
  <context:component-scan base-package="com.botreeconsulting.lms.web"/>

  <!-- Use @Controller annotations for MVC controller definitions -->
  <mvc:annotation-driven />

  <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
   </bean>

</beans>

但似乎我搞砸了,因为它在部署时给了我以下错误:

java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'bookController' bean method 
public java.lang.String com.botreeconsulting.lms.web.BookController.meet()
to {[/book],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}: There is already 'bookController' bean method
public java.lang.String com.botreeconsulting.lms.web.BookController.greet() mapped.

现在的问题是这个控制器是否对文档中的内容进行建模?我觉得我没有正确理解它。请指导我对控制器进行建模以匹配有关多个默认处理程序的语句。

谢谢,阿米特

【问题讨论】:

    标签: spring-mvc spring-3


    【解决方案1】:

    如果您有如下所示的控制器,则除/book/edit 之外的所有请求都将被定向到mydefault(),而/book/edit 将被发送到meet()

    @Controller
    @RequestMapping("/book")
    public class BookController {
    
        @RequestMapping
        public @ResponseBody String mydefault() {
            return "Hi Book!";
        }
    
        @RequestMapping("/edit")
        public @ResponseBody String meet() {
            return "Nice to meet you Book!";
        }
    }
    

    在您的示例中,您有两种没有显式路径映射的方法。

    【讨论】:

    • mydefault() 将只处理 /book 而不是 /book/abc。
    • 阿伦,If you have multiple such default methods...。是否可以配置多个默认方法?
    • 多个默认值是什么意思?在任何设计中都只有一个默认值
    • 阿伦,我知道控制器中只有一个默认值。现在这个 Spring 文档评论怎么会说 If you have a single default method (without explicit path mapping), then all requests without a more specific mapped method found will be dispatched to it. If you have multiple such default methods, then the method name will be taken into account for choosing between them
    • 我认为这意味着如果您有多个没有 url 映射的方法(即只有 @RequestMappin 没有指定路径),那么将考虑方法的名称。假设在上面的示例中,您添加了一个名为 add 并带有注释 @RequestMapping 的方法,然后您请求 /book/add 然后将调用 add 方法。
    【解决方案2】:

    Arun,您的回答是正确的,但需要注意的是,在 Spring 3.1 中它取决于配置了哪个 HandlerMapping-HandlerAdapter 对。

    自 Spring 2.5 以来一直在使用的 DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 支持所描述的行为,并且在未定义其他 HandlerMapping 和 HandlerAdapter bean 时仍默认启用。

    在 Spring 3.1 中添加的 RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter(参见 Spring 3.1 参考文档)作为前者的替代品不支持相同的行为——即在不明确的映射以及具有默认值的情况下使用方法名称方法(当没有定义显式映射时)。默认情况下,新的 HandlerMapping-HandlerAdapter 对从 MVC 命名空间和 MVC Java 配置中启用,建议在以后使用。

    Arun 引用的 Java 文档需要更新。我已经为 SPR-9042 创建了一张票。

    【讨论】:

    • 嗨,罗森。您能否澄清一下enabled by default from the MVC namespace 的声明——您的意思是&lt;mvc:annotation-config&gt; 标签,还是标签注册了另一对HandlerMapping/HandlerAdapter?
    • 另外,你能看看stackoverflow.com/questions/13671776/… - 在这个问题中,控制器只用'@Controller'注释,而它的单一方法被注释'@RequestMapping(“/hello”)'是吗?正确理解由于 Spring 3.1 中的更改,此配置仅适用于 3.1 之前的版本(没有&lt;mvc:annotation-driven&gt; 标签)?
    猜你喜欢
    • 2015-07-09
    • 2014-06-21
    • 2015-05-10
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 2016-02-24
    相关资源
    最近更新 更多