JSessionId происходит во всех URL -адресах, которые генерируются JSTL TAG

StackOverflow https://stackoverflow.com/questions/1045668

  •  20-08-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

Это не ошибка, это дизайн. Когда создается новый сеанс, сервер не уверен, поддерживает ли клиент файлы cookie или нет, и поэтому он генерирует файл cookie, а также JSessionId на URL. Когда клиент возвращается во второй раз и представляет файл 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.

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

На Tomcat 7 или любом сервере Servlet Specification V3 вы можете отключить jsessionId в URL, добавив следующее в web.xml вашего приложения

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

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

Если у вас есть общая страница обертки, которую используют все страницы (для меня это было обычным явлением), вы можете добавить session="false" на ваш <%@ page Чтобы удалить сеанс.

Пример 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