我有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) {
}
}
以下网址匹配两个映射: /home.html
但是,我想确保'内容'映射始终优先于'home'映射。有没有办法可以指明?
答案 0 :(得分:4)
最近我遇到了类似的问题:我有两种不明确的网址:
/2012
,/2013
等。我使用正则表达式创建了这样的表格:@RequestMapping("/{year:(?:19|20)\\d{2}}")
@RequestMapping("/{slug}")
。重要的是"年"控制器方法优先于" slug"一。不幸的是(对我而言)Spring总是使用" slug"控制器方法。
由于Spring MVC更喜欢更具体的映射,我不得不制作我的" slug"模式不太具体。根据{{3}}文档,我在slug映射中添加了通配符:@RequestMapping("/{slug}**")
我的控制器看起来像这样,现在listByYear
在一年(/2012
,/1998
等)在网址中时被调用。
@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";
}
}
这并不是如何设置优先级(在我看来这将是一个惊人的功能),但提供某种"很好的"解决方法,将来可能会派上用场。
答案 1 :(得分:0)
URL映射由发现映射的顺序决定。
因此,您可以强制在另一个控制器之后的spring上下文中创建一个控制器。
可以使用bean定义中的depends-on =“”属性(在xml中)来完成。
我不确定它是使用它找到的第一个映射还是最后一个映射。
另外,这只是理论,我实际上没有尝试过这个。
我看到这样的日志消息:
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上看看它是如何工作的。
答案 2 :(得分:0)
对特定的做的自动排序现在可以正常工作了。 (使用Spring 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);
}
答案 3 :(得分:-3)
此网址(/home.html)与两个映射都不匹配:
@RequestMapping(value = "**/{content}.html")
...
@RequestMapping(value = "**/home")
…
它只匹配第一个,因为它有一个后缀“ .html ”!