每个请求的上下文路径都可以改变吗?

May context path change on every request?

我正在开发一个 Web 应用程序,但发生了一些非常奇怪的事情。我 运行 我在本地 tomcat 上的 JEE 应用程序,一切顺利。当我在线部署我的应用程序时(在 Heroku 或 Openshift 上),上下文路径会根据每个请求发生变化。例如,如果我单击 link,该应用程序会正确显示我期望的内容,但从现在开始在上下文路径上(我在 JSPs 中使用它来生成 links ) 更改为当前 url。如果我将浏览器中的 url 修改为网站的主页,它会再次发生变化。可能是配置问题?我头疼。 我正在使用 urlrewrite 来获得漂亮的 urls,因此,如果我的网站主页是 http://homesite/ , an article is on http://homesite/article/year/month/article_slug。当我在主页上单击 link 以查看文章时,页面会相应地发生变化。页面更改后,如果我单击菜单中的 "Home" link(使用 ${pageContext.request.contextPath} 生成),它会转到我已经进入的同一页面。 在站点的每个页面中,我都添加了一个 javascript 变量,如下所示:

<script type="text/javascript">
    context = "<%=request.getContextPath()%>";
</script>

这里的 contextpath 总是空的,我相信它一定是空的。 这是生成我网站主菜单的 JSP 的内容:

<nav class="red accent-4">
    <div id="uc-nav-menu-container" class="nav-wrapper">
        <!--<a href="#" class="brand-logo right">Unical Coin</a>-->
        <a href="#" data-activates="mobile-demo" class="button-collapse left"><i class="material-icons">menu</i></a>
        <ul id="nav-mobile" class="left hide-on-med-and-down">
            <li class="active"><a href="${pageContext.request.contextPath}">Home</a></li>
            <li><a href="#">Mission</a></li>
            <li><a href="#">Tecnologia</a></li>
            <li><a href="#">About</a></li>
            <li><a href="#">Links</a></li>
        </ul>
        <ul class="red accent-4 side-nav" id="mobile-demo">
            <li class="active"><a href="${pageContext.request.contextPath}">Home</a></li>
            <li><a class="white-text" href="#">Mission</a></li>
            <li><a class="white-text" href="#">Tecnologia</a></li>
            <li><a class="white-text" href="#">About</a></li>
            <li><a class="white-text" href="#">Links</a></li>
        </ul>
        <div id="uc-user-menu-container" class="right"></div>
    </div>
</nav>

这是生成文章页面的JSP:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <jsp:include page="/WEB-INF/components/imports/default-head-imports.jsp"></jsp:include>
    </head>
    <body class="blue-grey lighten-5">
        <jsp:include page="/WEB-INF/components/nav-menu.jsp"></jsp:include>
        <div class="container">
            <jsp:include page="/WEB-INF/components/single-article-content.jsp"></jsp:include>
        </div>
        <jsp:include page="/WEB-INF/components/footer.jsp"></jsp:include>
        <jsp:include page="/WEB-INF/components/imports/default-foot-imports.jsp"></jsp:include>
    </body>
</html>

每个页面中的javascript变量仅在包含“/WEB-INF/components/imports/default-head-imports.jsp”中生成。

这里的问题是 ROOT 应用程序的上下文路径实际上是“”(空字符串)而不是您可能期望的 /。如果您以 ROOT 身​​份部署应用程序,您的 "Home" link 将如下所示:

<li class="active"><a href="">Home</a></li>

因此,如果您单击 link。

,您将到达当前页面

如果你真的想转到当前上下文的根目录,你的 link 需要这样做:

<li class="active"><a href="${pageContext.request.contextPath}/">Home</a></li>

请注意 href 属性中结尾的 /

如果您要对用户进行身份验证,那么如果 cookie 不可用,您实际上还应该使用 links 的正确编码来保留用户的会话:

<li class="active"><a href="$response.encodeURL("${pageContext.request.contextPath}/")">Home</a></li>

(这可能不是有效的 EL...我不是 EL 专家,但你明白了。)

哦,虽然 / 可能是 "legal" 上下文路径,但它不太可能为您提供预期的结果。永远不要将 path 放在 <Context> 元素中,也不要将 <Context> 元素放在 server.xml 中,除非绝对必要。相反,使用 WAR 文件名或部署描述符 XML 的文件名将上下文部署到所需路径,如果您希望它成为根 Web 应用程序,则包括 ROOT