【问题标题】:Spring MVC Servlet Mapping, differences between "/xxx" and "/xxx/*"Spring MVC Servlet Mapping,“/xxx”和“/xxx/*”的区别
【发布时间】:2019-10-02 18:02:30
【问题描述】:

我对 Spring MVC 的 url-pattern 映射的工作原理感到困惑。

当'getServletMappings'返回“/”时,我可以用“http://localhost:8080/hello”得到正确的响应。

但如果我将其更改为“/app”并将 url 更改为“http://localhost:8080/app/hello”则不起作用,它会返回 404 错误。

我是不是误会了什么,我也发现“/app/*”可以工作(我可以理解这个),但是为什么不能“/app”?

请检查我的代码:

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {
        // works with http://localhost:8080/hello
        return new String[] {
                "/"
        };
        // NOT working with http://localhost:8080/app/hello
        // return new String[] {
        //      "/app"
        //};
    }
}



@RestController
public class HTTPMethodsController {
   @RequestMapping("/hello")
   public String hello() {
       return "Hello SpringMVC.";
   }
}

【问题讨论】:

    标签: java spring-mvc servlet-mapping


    【解决方案1】:

    根据Servlet specification Chapter 12.2,servlet的映射必须使用如下语法:

    • 以“/”字符开头并以“/*”后缀结尾的字符串用于 路径映射。
    • 以“*.”前缀开头的字符串用作扩展映射。
    • 空字符串 ("") 是一种特殊的 URL 模式,它精确映射到应用程序的上下文根,即表单应用程序上下文根的请求,即http://host:port// 形式的请求。在这种情况下,路径信息是“/”,servlet 路径和上下文路径是空字符串 (“”)。
    • 仅包含“/”字符的字符串表示 应用。在这种情况下,servlet 路径是请求 URI 减去上下文路径,并且路径信息为空。
    • 所有其他字符串仅用于完全匹配。

    因此,将DispatcherServlet 映射到 URL "/app" 会导致 servlet 容器仅在完全匹配时将请求路由到它,这意味着仅当您将 url 更改为“http://localhost:8080/app”时。这样就没有空间为目标特定的 Spring 控制器添加额外的路径(更准确地说:如果您使用 @RequestMapping("/app") 映射它,您实际上可以点击您的 hello() 控制器方法,因为 DispatcherServlet 回退到使用整个 url 进行搜索,但实际上这不是你想要的)。

    所以映射“/app/*”是正确的,或者您也可以将其映射为默认的servlet,如您所见。

    【讨论】:

      猜你喜欢
      • 2016-01-13
      • 1970-01-01
      • 2011-11-25
      • 2014-10-03
      • 2012-01-15
      • 1970-01-01
      • 2018-03-06
      • 2020-02-08
      • 1970-01-01
      相关资源
      最近更新 更多