有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有两个spring控制器映射:

@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) {
    }
}

以下url匹配这两个映射: /家。html

但是,我希望确保“内容”映射始终优先于“主”映射。有什么办法可以具体说明吗


共 (4) 个答案

  1. # 1 楼答案

    此url(/home.html)不匹配两个映射:

        @RequestMapping(value = "**/{content}.html")
        ...
        @RequestMapping(value = "**/home")
        …
    

    它只与第一个匹配,因为它有一个后缀“.html

  2. # 2 楼答案

    我最近遇到了非常类似的问题,我必须处理两种不明确的URL:

    • 一个是接受一年,比如说/2012/2013等等。我使用正则表达式的映射创建了它:@RequestMapping("/{year:(?:19|20)\\d{2}}")
    • 另一个是接受内容标识符(又名slug)。我使用类似@RequestMapping("/{slug}")的映射创建了它

    重要的是,“年”控制器方法优先于“slug”控制器方法。不幸的是(对我来说),Spring总是使用“slug”控制器方法

    由于SpringMVC更喜欢更具体的映射,我不得不使我的“slug”模式不那么具体。基于Path Pattern Comparison文档,我向slug映射添加了通配符:@RequestMapping("/{slug}**")

    我的控制器看起来是这样的,现在当一年(/2012/1998等)在URL中时调用listByYear

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

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

    这并不完全是如何设置优先级(在我看来这将是一个惊人的特性),而是提供某种“好”的解决方法,在将来可能会很方便

  3. # 3 楼答案

    现在,Specify上的自动订购功能可以按预期工作。(使用弹簧5.0.10)

    AntPatternComparator

            /**
             * Compare two patterns to determine which should match first, i.e. which
             * is the most specific regarding the current path.
             * @return a negative integer, zero, or a positive integer as pattern1 is
             * more specific, equally specific, or less specific than pattern2.
             */
            @Override
            public int compare(String pattern1, String pattern2)
    

    AbstractUrlHandlerMapping::lookupHandler(String urlPath, HttpServletRequest request)开始使用

            Comparator<String> patternComparator = getPathMatcher().getPatternComparator(urlPath);
            if (!matchingPatterns.isEmpty()) {
                matchingPatterns.sort(patternComparator);
                if (logger.isDebugEnabled()) {
                    logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
                }
                bestMatch = matchingPatterns.get(0);
            }
    
  4. # 4 楼答案

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

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

    这可以使用bean定义(xml)中的depends-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'
    

    因此,值得在SimpleUrlHandlerMapping上一试,看看它是如何工作的