我正在尝试编写最简单的Spring应用程序,该应用程序在@RequestMapping中使用多个路径元素。例如,/ appcontext / blog / hello-world.html应该在请求映射中工作(显然/ appcontext是我的应用程序的上下文)。
Spring可以做那样的事吗?当它只映射一件事时,我可以轻松地工作。例如:
@RequestMapping( “你好世界”)
工作并将匹配/hello-world.do,/anything/hello-world.do,但我的问题是,我试图只匹配hello-world,如果它在/ blog路径中,并且每当我使用类似的东西:
@RequestMapping( “/博客/你好世界”)
它永远不会触发。
服务器日志,例如:
INFO: Mapped "{[/blog/hello],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mainweb.BlogController.foo()
看起来它应该可以工作(并且它是我唯一的请求映射),但随后:
WARNING: No mapping found for HTTP request with URI [/context/blog/hello.html] in DispatcherServlet with name 'dispatcher'
Spring可以这样做吗?我不想把所有的请求映射都放在/中,因为它会变得一团糟。
我唯一可以使用的映射是:
@RequestMapping("/**")
从那里,我可以直接查看HttpServletRequest对象,但这似乎打败了@RequestMapping的整个过程。
这是我的控制器:
@Controller
public class BlogController {
private static final Logger LOG = Logger.getLogger(BlogController.class.getName());
@RequestMapping("/blog/hello")
public String foo1() {
LOG.info("foo1");
return "nothing";
}
@RequestMapping("/blog/hello.html")
public String foo2() {
LOG.info("foo2");
return "nothing";
}
@RequestMapping("/blog/hello.*")
public String foo3() {
LOG.info("foo3");
return "nothing";
}
@RequestMapping("/blog/**")
public String foo4() {
LOG.info("foo4");
return "nothing";
}
@RequestMapping("/blog/{path}")
public String foo5(@PathVariable String path) {
LOG.info("foo5 " + path);
return "nothing";
}
// added this as a test - it's the only way that this controller works
@RequestMapping("/**")
public String foo6() {
LOG.info("foo6");
return "nothing";
}
}
如果我没有foo6映射,那么无论我使用什么网址,这都没有任何作用。
当我使用该控制器时,这是服务器日志中显示的内容:
INFO: Mapped "{[/blog/hello],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mainweb.BlogController.foo1()
INFO: Mapped "{[/blog/hello.html],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mainweb.BlogController.foo2()
INFO: Mapped "{[/blog/hello.*],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mainweb.BlogController.foo3()
INFO: Mapped "{[/blog/**],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mainweb.BlogController.foo4()
INFO: Mapped "{[/blog/{path}],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mainweb.BlogController.foo5(java.lang.String)
INFO: Mapped "{[/**],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String mainweb.BlogController.foo6()
但是,如果我把它放进去,除了foo6之外什么都没有触发。
谢谢!
编辑:我创建了一个非常简单的项目,它只有一个类,Controller,有一个方法,RequestMapping。除了不工作,这个项目什么都不做。除了使用通配符之外,根本无法让@RequestMapping执行任何操作。这似乎是Spring中的一个关键错误;所有文件都说@RequestMapping不只是映射一个通配符。
答案 0 :(得分:0)
在我看来,它未在/ blog路径中映射的原因是您没有使用该路径来访问它。
根据您在上述问题中发布的错误,您已定义/映射:
/blog/hello
您尝试访问:
/context/blog/hello.html
即。您在URI前面加上“/ context”,并以“.html”为后缀。这就是它没有回应的原因。
我建议您尝试访问已映射的URI。但是,您可能还需要确保应用程序的根上下文正确无误。
请注意,通过添加“.html”后缀,您没有使用您定义的路径。如果你想使用诸如此类的随机后缀,那么也可以在映射中使用wildrcards。即@RequestMapping(value =“/ blog / hello **”)
但是,如果可以避免使用通配符,我通常会建议不要使用通配符,因为当您向应用程序添加更多映射时,它们可能会产生一些惊喜。
编辑 - 我还发现你的控制器正在搞乱这些映射。只需阅读以下映射: @RequestMapping( “/博客/你好”) @RequestMapping( “/博客/ hello.html的”) @RequestMapping( “/博客/你好。*”)
你的映射相互冲突。该列表中的第一个映射是其他映射的子集,因此它将用于与这些映射中的任何映射匹配的任何URL。即第二个2是多余的。您可以通过将'bare'/ blog / hello放在另一个2之后来修复它,以便首先获取更具体的映射,但是,依赖于编写方法的顺序似乎要求麻烦我
答案 1 :(得分:0)
想出来。 servlet-mapping切断了部分路径! servlet-mapping基本上创建了一个迷你上下文。我不知道它是那样做的,而且直觉上并不明显,但这就是发生的事情。