JSESSIONID
Два веб-приложения о предыдущей записи в блоге/a/
и /b/
поддерживать свои собственные JSESSIONIDs, и были обновлены , чтобы показать его. Создайте и разверните приложение, как и раньше, и, используя Chrome, по очереди посетите эти два сайта : http: // localhost: 8080 / a / AFilterThatOutputsTheRequestsThreadID http: // localhost: 8080 / b / AServletThatOutputsTheRequestsThreadID
В Менеджере файлов cookie Chrome (Chrome prefs), вот cookie для «localhost», относящегося к /a/
контексту, после нажатия на URL :
Обратите внимание, что поле «Путь» совпадает с именем веб-приложения.
Значение для / b / во многом совпадает, но отличается строковым значением JSESSIONID, которое вы наблюдали, когда посещали URL-адреса.
Если вы идете один дальше и перейти в один из URL — адресов , которые использует getServletDispatcher (..). Включают (..) , чтобы соединить два веб — приложения, то вы увидите только JSESSIONID для /a/
использования для обоих.
Сервлеты Java в сравнении с правилами cookie браузера
Браузер не знает о серверных веб-приложениях Java; в частности, тот факт, что они хотят поддерживать разные JSESSIONID для каждого «контекста» ( /a/
и /b/
являются разными контекстами в контейнере сервлета). Браузер воспринимает их как каталоги и не делает того же различия, что контейнеры Java-сервлетов.
Теоретическая проблема
В браузере может быть один cookie-файл JSESSIONID, смонтированный в root ( /
), который будет разрешен для взаимодействия браузера и веб-приложений «a» и «b» с сервером. Браузер подумает, что может отправить запрос, а Tomcat не узнает, что произошло.
Для нашего примера «a» и «b», как есть, с двумя файлами cookie, разделенными путями, теоретическая проблема остается именно такой.
Делая проблему реальной
Что если приложение /b/
вместо этого было смонтировано в корневом контексте ( /
)? Эффективно превращая «a» в подкаталог «b» в отношении браузера. Ну, у меня есть ветка Github, которая показывает только это:
git checkout b_is_now_root mvn clean install ./copy_war_files.sh cd apache-tomcat-7.0.41/bin ./catalina.sh run
Перво-наперво — удалите все куки для localhost в Chrome Cookie Manager.
Затем перейдите на страницу http: // localhost: 8080 / AServletThatOutputsTheRequestsThreadID (обратите внимание, что мы удалили/b/
часть URL-адреса ). Теперь у нас есть один cookie на localhost, и он сопоставлен с /
(корневым) путем. Вы можете увидеть это в диспетчере файлов cookie.
Теперь давайте перейдем на http: // localhost: 8080 / a / AFilterThatOutputsTheRequestsThreadID для другого веб-приложения. На этот раз мы увидим это начальное взаимодействие с вкладкой сети инспектора Chrome:
Обратите внимание на корневой контекст JSESSIONID, идущий на сервер Tomcat, и второй JSESSIONID, сопоставленный с /a/
возвращением.
Если для этого мы нажмем обновить в браузере, то оба будут отправлены в сервлет-контейнер с запросами, и это останется неизменным на протяжении всего жизненного цикла этого сеанса и контейнера сервлета:
В конце концов, контейнер сервлетов устраняет неоднозначность, так как он точно передает запросы в ‘a’ или root (бывший ‘b’).
Не только для удушения …
Конечно, это шире, чем стратегия задушить старое веб-приложение. Это влияет на любую ситуацию, в которой вы можете сделать несколько разумных хостингов для двух веб-приложений в одном домене из одного контейнера сервлета.
Желал для …
Было бы неплохо, чтобы механизм внутри context.xml Tomcat принудительно устанавливал один JSESSIONID для всех размещенных веб-приложений в одном домене. Примечание. Я не прошу, чтобы несколько приложений имели объединенные хранилища сессий внутри контекста сервлета (request.getSession () и т. Д.), Просто идентификаторы будут одинаковыми. В Servlet spec 3.x есть некоторые вещи, которые выглядят так, как будто вы можете переопределить значения пути по умолчанию для файлов cookie, но я не играл с этим.
Обновление: есть такой элемент конфигурации для context.xml Tomcat7: <Context ... sessionCookiePath="/" > ... </Context>