spring 中带有 url 模式重定向的上下文路径

Context path with url-pattern redirect in spring

我对 tomcat 服务器上的路径和 url 有点困惑,让我解释一下:

我的 tomcat webapp 目录是:/server

我已经在目录 /server/myapp/subfolder

中部署了一个 spring 应用程序

这意味着我的上下文路径 /server/myapp

我的 servlet 有一个 url-模式 /subfolder/*

可以在 url http://server.com/myapp/subfolder/

访问我的 servlet

在我的许多 spring 控制器中,我 return 重定向:

return "redirect:/item/list";

这会将访问者重定向到 http://server.com/myapp/item/list

这当然会导致 404,因为正确的 url 是:http://server.com/myapp/subfolder/item/list

这可以很容易地解决,只需将所有内容都放在一个单独的 webapp 中或简单地删除 url-pattern。但两者都是不可能的,因为单独的 webapp 意味着不同的类加载器(导致其他系统出现问题)并且 url-类似 / 的模式将与服务器上运行的其他应用程序冲突。

我可以将我的重定向更改为 "redirect:/subfolder/item/list",这将修复重定向。

是否有更好的解决方案,这样我就不必在使用上下文路径的任何地方手动添加 "subfolder/"?

最后我简单做了一个util函数:

public String redirect(String path){
    return "redirect:/subfolder"+path;
}

有点hacky,但它允许我快速更改"subfolder"以防url-模式发生变化。

视图中的@url 标签也使用了上下文路径,因此我创建了自己的@url 标签,将"subfolder" 添加到上下文路径。

Spring 现在看起来很开心,我再也没有收到任何 404 了。

您可以从 HttpServletRequest.getContextPath() 获取它,而不是硬连接您的应用上下文路径。

Spring 有 ServletUriComponentsBuilder 可以发挥你的优势。您可以将当前请求传递给它,并让它附加到您想要转到的位置。节省您硬编码 /subfolder 或您所做的任何事情。

UriComponents uri = ServletUriComponentsBuilder
                            .fromServletMapping(request)
                            .fromPath("/item/list")
                            .build();
return "redirect:" + uri.toUriString();

当然你可以把它放在一个实用方法中。这仅在您重定向到同一 DispatcherServlet 中的 URL 时有效。

我知道这是一个老问题,但如果有人正在寻找当前答案,RedirectView(至少在最新的 5.0.9 版本中)有一个默认为 false 的 contextRelative 布尔参数。将其设置为 true 使重定向上下文相对。例如:

return new RedirectView("/account", true);

参考:docs