我有一些奇怪的错误:当我在某些浏览器中首次打开页面时,所有参考都具有JSessionId参数(例如 <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).

当我按F5或以任何其他方式刷新页面时,所有这些内容都消失了,并且一切正常,直到我关闭浏览器(也应该关闭所有选项卡)。当我再次打开它时,我会看到这个奇怪的jsessionid参数。

我使用JSTL <c:url..> 用于创建所有URL的标签。

我已经读过一段时间,如果禁用了cookie,jsessionId是cookie的替代方法,但是启用了cookie,我实际上不使用cookie。

有帮助吗?

解决方案

这不是一个错误,而是设计。创建新的会话时,服务器不确定客户端是否支持cookie,因此它会在URL上生成cookie以及jsessionId。当客户端第二次回来并呈现cookie时,服务器知道不需要JSessionID,并在其余的会话中将其丢弃。如果客户端没有cookie返回,则服务器需要继续使用JSessionId重写。

您可能不会明确使用cookie,但是您确实有一个会话,并且容器需要跟踪该会话。

其他提示

正如所解释的 斯卡夫曼的答案, 它不是错误。这是一种预期的行为.

在您的问题中,jsessionID被称为参数,情况并非如此。
使用
<c:url value="/"/>
将产生以下内容: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
所以使用
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
会生成
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
,因此您的服务器找不到可用的资源。

我发现最好的解决方法是 利用 ${pageContext.request.contextPath} 代替 <c:url value="/"/>. 。因此,在上一个示例中,您将有
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
那将产生
/some/stylesheets/style.css.

这个解决方案是 集装箱独立 (而Servlet规范符合V3的容器(如Tomcat)不是)。过滤响应URL感觉就像是一个黑客,因为您需要更改默认行为。但这一切都取决于您需要和想要实现的目标。

在tomcat 7或任何servlet规范v3符合v3的服务器上,您可以通过在您的应用程序的web.xml中添加以下来禁用URL中的jsessionId。

<session-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

这是一个令人讨厌的解决方法 Filter 因此,每当客户支持cookie时,您将永远不会在URL中看到JSessionId。

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    HttpSession session = req.getSession();

    if (session.isNew()) {
        // New session? OK, redirect to encoded URL with jsessionid in it (and implicitly also set cookie).
        res.sendRedirect(res.encodeRedirectURL(req.getRequestURI()));
        return;
    } else if (session.getAttribute("verified") == null) {
        // Session has not been verified yet? OK, mark it verified so that we don't need to repeat this.
        session.setAttribute("verified", true);
        if (req.isRequestedSessionIdFromCookie()) {
            // Supports cookies? OK, redirect to unencoded URL to get rid of jsessionid in URL.
            res.sendRedirect(req.getRequestURI().split(";")[0]);
            return;
        }
    }

    chain.doFilter(request, response);
}

映射它 /* 或任何需要会话管理的URL模式。

如果您有所有页面使用的通用包装页(对我来说很常见),则可以添加 session="false" 给你 <%@ page 删除sessionID。

例子 common.inc

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="ab" tagdir="/WEB-INF/tags" %>

<c:set var="contextPath" scope="request" value="${ pageContext.request.contextPath }" />
<c:set var="assetPath" scope="request" value="/assets" />
<c:set var="debugEnabled" scope="request" value="${ applicationDebugProperties.debugEnabled }" />

另外..设置值 c:url 变量并使用 c:out escapeXml="false" 要输出变量,这将删除sessionID。

例子:

<c:url value=${url} var="image"/>
<c:out var=${image} escapeXml="false"/>

另外,您可以将其添加到Apache配置中以截断SessionID。

ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]

不幸的是,我发现的唯一方法是在您的应用程序中添加过滤器,以剥离JSessionId参数。如果您要创建公共网站并希望该搜索引擎索引您的页面,这尤其令人讨厌。

我不认为可以将tomcat(如果您正在使用的话)配置为不将其添加到您的URL中。我不能为其他服务器说。

但是,请注意,如果您确实创建了过滤器,则需要会话管理,并且用户有cookie关闭,您将遇到问题。

一个解决方法不使用 <c:url>, ,但是使用 ${request.contextPath}/path

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top