【问题标题】:Two Spring Controllers matching to the same URL result in wrong controller call匹配相同 URL 的两个 Spring Controller 会导致错误的控制器调用
【发布时间】:2015-04-09 23:11:43
【问题描述】:

我们遇到了两个碰巧相互干扰的弹簧控制器的问题。 一个控制器通过通配符前缀匹配 URL 后缀。另一个控制器匹配一个 URL 前缀。我希望从左到右读取 URL,但似乎并非如此。

考虑以下代码(已编辑):

    @RequestMapping(value = "/**/abcdefg")
    public class Controller1 {...}

    @RequestMapping(value = "/**/xyz")
    public class Controller2 {...}

    @RequestMapping(value = "/some/{path}")
    public class Controller3 
    {
        @RequestMapping(value = "/{page}", method = RequestMethod.GET)
        public String page(@PathVariable("page") final String page, final Model model)
        { //do sth }
    }

现在的问题是,如果调用 URL“/some/path/abcdefg”,Controller1 就会启动。但我想要 Controller3。

不幸的是,这种行为与其他控制器不一样!

如果 URL “/some/path/xyz” 被调用,Controller3 就会启动。这种行为对于控制器来说是可重现的。它的行为始终相同,并且控制器不是随机选择的。

spring 文档以及其他用户提出的问题都指向了这个想法,即采用与给定模式匹配的“第一个”控制器。然而,这对我来说意义不大,因为 Controller1 和 2 有一个 非常 相似的请求映射,但控制器的匹配却不同!

一切都由调度程序 servlet 处理。

有没有人暗示可能会发生什么?

【问题讨论】:

  • 映射到/some/path 的控制器将无法处理/some/path/xyz。请向我们展示您的真实映射。
  • /some/path 怎么能匹配/some/path/abcd?他们显然不平等。 真正的路径是什么?
  • 感谢您的快速 cmets!我编辑了代码。确实有一个带有请求映射的控制器方法,“有时”会接听电话,“有时”不会

标签: java spring spring-mvc controller


【解决方案1】:

这部分我希望从左到右读取 URL,但似乎并非如此。 你说得对,但事实并非如此。映射由特异性解决,相关文档可用here

URI 变量和通配符数量较少的模式是 考虑更具体。例如/hotels/{hotel}/* 有 1 个 URI 变量和 1 个通配符,被认为比 /hotels/{hotel}/** 其中 1 个 URI 变量和 2 个通配符。

如果两个模式的计数相同,则较长的一个是 考虑更具体。例如/foo/bar* 更长并且 被认为比/foo/* 更具体。

当两个模式具有相同的计数和长度时,模式与 更少的通配符被认为更具体。例如 /hotels/{hotel}/hotels/* 更具体。

如果两个映射匹配一个请求,将应用更具体的映射。根据您的要求制定映射以遵循特定规则

【讨论】:

  • 非常感谢先生!你刚刚拯救了我的一天。我刚刚编辑了我的问题以指出你是对的。 "/**/abcdefg"、"/**/xyz" 和 "/some/{path}/{page}" 有相同数量的 uri-vars / 通配符。无论如何,“abcdefg”的字符比“some”多,而“xyz”的字符少。这意味着,Spring 将“abcdefg”作为最具体的匹配处理,然后是“some”,然后是“xyz”欢呼。这应该以大写字母打印到春季起始页。
猜你喜欢
  • 2013-07-09
  • 2012-12-03
  • 2016-03-30
  • 2019-06-19
  • 2018-12-21
  • 1970-01-01
  • 2023-03-18
  • 2015-03-25
  • 1970-01-01
相关资源
最近更新 更多