在Spring MVC中的servlet映射中,如何映射url模式目录的根目录?

10
<servlet-mapping>
    <servlet-name>testServlet</servlet-name>
    <url-pattern>/test/*</url-pattern>
</servlet-mapping>
如果我访问 /test/page,上述内容将起作用。但是,访问/test/test/将不起作用。 我正在使用Spring MVC,我的请求映射如下:
@RequestMapping(value = {"","/"})

编辑:

我正在与一个独立项目进行验证,但这似乎是Spring的UrlPathHelper中存在的一个错误。当同时存在上下文和servlet路径时,并且您在没有尾随斜杠的情况下访问servlet时,下面的方法将返回一个不正确的路径。

public String getPathWithinApplication(HttpServletRequest request) {
    String contextPath = getContextPath(request);
    String requestUri = getRequestUri(request);
    if (StringUtils.startsWithIgnoreCase(requestUri, contextPath)) {
        // Normal case: URI contains context path.
        String path = requestUri.substring(contextPath.length());
        return (StringUtils.hasText(path) ? path : "/");
    }
    else {
        // Special case: rather unusual.
        return requestUri;
    }
}

举个例子,假设我有一个上下文为“admin”,并拥有以下的Servlet映射:

<servlet-mapping>
    <servlet-name>usersServlet</servlet-name>
    <url-pattern>/users/*</url-pattern>
</servlet-mapping>

现在我的一个控制器中有一个请求映射,像这样:

@RequestMapping(value = {"","/"})

如果我访问 /admin/users,它将无法正常工作。但是,如果我访问 /admin/users/,它将能够正常工作。现在,如果我将我的请求映射更改为以下内容,则两个都将工作:


@RequestMapping(value = {"/users","/"})

然而,现在URL /admin/users/users 也可以使用(这并不是我想要的)。

5个回答

5

Yevgeniy是正确的,但如果您的DispatcherServlet正在接管默认servlet,则必须将以下内容添加到web.xml中:

<welcome-file-list>
    <welcome-file>/</welcome-file>
</welcome-file-list>

3

通常我的设备配置如下:

<servlet-mapping>
    <servlet-name>testServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

控制器,假设您想同时处理/test/test/

@Controller
public class MyController {

    @RequestMapping("/test")
    public String test() {
        return "redirect:/welcome";
    }

    @RequestMapping("/test/")
    public String test() {
        return "redirect:/welcome";
    }

    @RequestMapping("/welcome")
    public void test(ModelMap model) {
        // do your stuff
    }
}

这样设置会导致DispatcherServlet处理*.css*.js文件的请求,这在大多数情况下是不希望的。我认为这就是Bhavik所描述的问题。对于这些资源,你可以像这样使用ResourceController:
<mvc:resources mapping="/css/**" location="/resources/css/" />
<mvc:resources mapping="/js/**" location="/resources/js/" />

您无需编写额外的控制器即可提供来自/resources/css/resources/js的文件。


问题是关于根控制器的,更多参考请阅读我下面的答案。 - Bhavik Ambani
感谢您对服务资源的评论。这里是官方的Spring文档。 - David

2
首先,将映射分派器servlet到“ /”和“ /*”之间的区别。这是有区别的!
当映射到“ /*”时,所有URL请求(包括像“ /WEB-INF/jsp/.../index.jsp”这样的请求)都被映射到分派器servlet。
其次,在使用Spring + Tiles时,如果在tiles定义中返回一些JSP,则它被视为内部转发请求,并由与原始请求相同的servlet处理。在我的示例中,我调用了根URL“ /”,这个URL被home()方法正确捕获,然后由Tiles转发到“ index.jsp”,再次由Dispatcher Servlet处理。显然,分派器servlet无法处理“ index.jsp”,因为没有为它提供控制器。
是的,这很丑陋,但看起来就是这样工作的。
因此,我目前找到的唯一解决方案是:将“ /*”更改回“ /”在web.xml中。这样,JSP将由Tomcat的jsp servlet正确呈现,而不是dispatcher servlet。不幸的是,这个修复程序会破坏Spring的ROOT URL分派,所以你需要暂时放弃使用ROOT URL + Tiles的想法。
请注意,在使用“ /*”时,在web.xml中添加显式servlet映射“ .jsp - > Tomcat jsp”是无效的,而且很糟糕。
仍然存在问题。
此外,这是Spring MVC 3.0中的问题。

问题不在于使用根路径。如果我使用根路径,那么我总是会选择<url-pattern>/</url-pattern>@RequestMapping(value = {"","/"})。我从来没有遇到过这样的问题,而且我正在使用Tiles 2和Spring MVC 3。问题在于首先指定servlet路径。每当您指定servlet路径信息时,Spring的请求映射就是在此之后的所有内容。因此,从技术上讲,相同的请求映射应该起作用,因为它是servlet路径的根。然而,事实并非如此。 - user4903

0
一种不需要触碰web.xml文件的方法是将映射设置为默认的欢迎文件路径。
@RequestMapping("/index.html")

0
在我的情况下,每个URL都能正常工作,除了根目录“/”的URL。 问题是我没有删除项目Web应用程序根文件夹中的index.htm文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接