RequestMapping包含多个路径元素

时间:2013-11-06 08:51:17

标签: spring mapping

我正在尝试编写最简单的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不只是映射一个通配符。

2 个答案:

答案 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基本上创建了一个迷你上下文。我不知道它是那样做的,而且直觉上并不明显,但这就是发生的事情。