Подтвердить что ты не робот

Jsessionid встречается во всех URL-адресах, которые генерируются тегом jstl <c: url..>

У меня есть странная ошибка: когда я открываю страницу в первый раз в каком-то браузере, все ссылки имеют параметр jsessionid (например, <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).

Когда я нажимаю F5 или обновляю страницу другими способами, все эти вещи исчезают, и все работает нормально, пока я не закрою браузер (и все вкладки тоже должны быть закрыты). Когда я его снова открою, я вижу этот странный параметр jsessionid.

Я использую тэг jstl <c:url..> для создания всех URL-адресов.

Я уже некоторое время читал, что jsessionid является альтернативой cookies, если файлы cookie отключены, но файлы cookie включены, и я фактически не использую файлы cookie.

4b9b3361

Ответ 1

Это не ошибка, это по дизайну. Когда создается новый сеанс, сервер не уверен, поддерживает ли клиент файлы cookie или нет, и поэтому он генерирует файл cookie, а также jsessionid в URL-адресе. Когда клиент возвращается во второй раз и представляет файл cookie, сервер знает, что jsessionid не требуется, и отбрасывает его на оставшуюся часть сеанса. Если клиент возвращается без cookie, тогда серверу необходимо продолжить использование перезаписи jsessionid.

Вы не можете явно использовать файлы cookie, но у вас неявно есть сеанс, и контейнер должен отслеживать этот сеанс.

Ответ 2

Как объяснено в ответе скаффмана, это не ошибка. Его ожидаемое поведение.

В вашем вопросе 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.

Это решение независимое от контейнера (тогда как спецификация сервлета v3, совместимая с контейнером, как Tomcat - решение отсутствует). Фильтрация URL-адреса ответа выглядит как хак, потому что вам нужно изменить поведение по умолчанию. Но все зависит от того, что вам нужно и чего вы хотите достичь.

Ответ 3

В Tomcat 7 или любом сервлет-спецификации, совместимом с сервером v3, вы можете отключить jsessionid в URL-адресе, добавив следующее в web.xml вашего приложения.

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

Ответ 4

Здесь неприятный обход в стиле Filter, чтобы вы никогда не увидели jsessionid в URL-адресе всякий раз, когда клиент поддерживает файлы cookie.

@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, который требует управления сеансом.

Ответ 5

Если у вас есть общая страница обертки, которую используют все страницы (для меня это было common.inc) вы можете добавить 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]

Ответ 6

К сожалению, единственный способ, которым я нашел это, - добавить фильтр к вашему приложению, который вычеркнет параметр jsessionid. Его особенно раздражает, если вы создаете общедоступный веб-сайт и хотите, чтобы поисковые системы индексировали ваши страницы.

Я не считаю, что tomcat (если это то, что вы используете) может быть настроен так, чтобы не добавлять это к вашему URL-адресу. Я не могу сказать для других серверов, хотя.

Однако обратите внимание, что если вы создаете фильтр, и тогда вам требуется управление сеансом, а у пользователя отключены файлы cookie, вы столкнетесь с проблемами.

Ответ 7

Один способ обхода - не использовать <c:url>, а использовать ${request.contextPath}/path