如何设置Spring MVC映射的优先级?

Jas*_*ltz 6 java spring spring-mvc

我有2个弹簧控制器映射:

@Controller
public class ContentController {

    @RequestMapping(value = "**/{content}.html")
    public String content(@PathVariable String content, Model model, HttpServletRequest request) {
    }
}

@Controller
public class HomeController {

    @RequestMapping(value = "**/home")
    public String home(HttpServletRequest request, Model model) {
    }
}
Run Code Online (Sandbox Code Playgroud)

以下url匹配两个映射:/home.html

但是,我想确保"内容"映射始终优先于"主页"映射.有没有办法可以指明?

Tom*_*Tom 5

最近我遇到了非常相似的问题,必须使用两种模棱两可的URL:

  • 一个人接受一年,比如说/2012/2013等等。我使用带有正则表达式的映射来创建它,如下所示:@RequestMapping("/{year:(?:19|20)\\d{2}}")
  • 另一个正在接受内容标识符(也称为slug)。我使用类似的映射创建了它@RequestMapping("/{slug}")

重要的是,“年”控制器方法要优先于“子弹”方法。不幸的是(对我而言)Spring始终使用“子弹”控制器方法。

由于Spring MVC 希望使用更具体的映射,因此我不得不使“子弹”模式不那么具体。根据路径模式比较文档,我在段映射中添加了通配符:@RequestMapping("/{slug}**")

我的控制器看起来像这样,现在在URL中输入listByYear年份(/2012/1998等等)时会被调用。

@Controller
public class ContentController
{
    @RequestMapping(value = "/{slug}**")
    public String content(@PathVariable("slug") final String slug)
    {
        return "content";
    }
}
Run Code Online (Sandbox Code Playgroud)

@Controller
public class IndexController
{
    @RequestMapping("/{year:(?:19|20)\\d{2}}")
    public String listByYear()
    {
        return "list";
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是设置优先级的确切方法(我认为这将是一个了不起的功能),但是提供了一种“不错”的解决方法,并且将来可能会派上用场。


Sol*_*ris 1

URL 映射由发现映射的顺序决定。

因此,您可以强制在 spring 上下文中在另一个控制器之后创建一个控制器。

这可以使用 bean 定义(在 xml 中)中的 dependent-on="" 属性来完成。

我不确定它是否使用它找到的第一个映射,还是最后一个。

另外,这只是理论,我还没有实际尝试过。

我看到这样的日志消息:

17:29:01.618 [main] INF S o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/resources/**] onto handler    'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
17:29:01.625 [main] INF S o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0'
Run Code Online (Sandbox Code Playgroud)

所以值得一看 SimpleUrlHandlerMapping 看看它是如何工作的。

  • 即使这确实有效,我认为也不会达到预期的效果。我相信 Spring 总是更喜欢更具体的映射。 (2认同)