Прежде всего, здесь объясняются требования. Процесс итерации версии SpringSession определенно будет сопровождаться удалением некоторых классов и добавлением некоторых классов. Версия, используемая в настоящее время в этой серии, представляет собой версию потока кода мастера объект на гитхабе. Если есть студенты, у которых есть сомнения по поводу некоторых классов или обработки в других версиях, милости просим к общению.
Эта статья познакомитSpringSession
средние дваsessionId
Стратегия синтаксического анализа, которая фактически упоминалась в предыдущей статье, будет вынесена и обсуждена здесь.SpringSession
серединаCookie
Узнайте о соответствующих стратегиях
Вниз.
Стратегия разрешения sessionId
SpringSession
среда дляsessionId
Стратегия, связанная с синтаксическим анализом, проходит черезHttpSessionIdResolver
Этот интерфейс отражен.HttpSessionIdResolver
Есть два класса реализации:
Эти два класса соответствуютSpringSession
РазобратьsessionId
две разные стратегии реализации. Прежде чем углубляться в детали реализации различных стратегий, давайте взглянемHttpSessionIdResolver
Каковы некоторые из поведений, определяемых интерфейсом.
HttpSessionIdResolver
HttpSessionIdResolver
ОпределенныйsessionId
Контракт на парсинг стратегии (Contract
). Позволяет разрешить sessionId с запросом и отправить sessionId с ответом или завершить сеанс. Интерфейс определяется следующим образом:
public interface HttpSessionIdResolver {
List<String> resolveSessionIds(HttpServletRequest request);
void setSessionId(HttpServletRequest request, HttpServletResponse response,String sessionId);
void expireSession(HttpServletRequest request, HttpServletResponse response);
}
HttpSessionIdResolver
Есть три метода:
-
resolveSessionIds
: разрешает текущий запрос, связанный сsessionId
.sessionId
может исходить отCookie
или заголовки запроса. -
setSessionId
: будет ли данныйsessionId
отправлено клиенту. Этот метод создает новыйsession
вызывается и информирует клиента о новомsessionId
что. -
expireSession
: Указывает клиенту завершить текущийsession
. когдаsession
Этот метод вызывается, когда он недействителен, и должен уведомить клиента.sessionId
Более не действителен. Например, он может удалитьsessionId
изCookie
, или установитеHTTP
Заголовок ответа, значение которого пусто, означает, что клиент больше не будет отправлятьsessionId
.
Ниже приводится подробный анализ двух упомянутых выше стратегий.
Анализировать sessionId на основе cookie
Класс реализации, соответствующий этой стратегии, равенCookieHttpSessionIdResolver
, начиная сCookie
получено вsession
; в частности, эта реализация позволит использоватьCookieHttpSessionIdResolver#setCookieSerializer(CookieSerializer)
уточнитьCookie
Стратегия сериализации. дефолтCookie
имя это "SESSION
".Создаватьsession
час,HTTP
Ответ будет содержать указанныйCookie name
а такжеvalue
даsessionId
изCookie
.Cookie
будет отмечен какsession cookie
,Cookie
изdomain path
использоватьcontext path
, и отмечен какHttpOnly
,еслиHttpServletRequest#isSecure()
вернутьtrue
,ТакCookie
будет помечен как безопасный. следующее:
о
Cookie
, вы можете обратиться к:Поговорим о сеансах и файлах cookie.
HTTP/1.1 200 OK
Set-Cookie: SESSION=f81d4fae-7dec-11d0-a765-00a0c91e6bf6; Path=/context-root; Secure; HttpOnly
В это время клиент должен указать тот жеCookie
включатьsession
Информация. Например:
GET /messages/ HTTP/1.1
Host: example.com
Cookie: SESSION=f81d4fae-7dec-11d0-a765-00a0c91e6bf6
Когда сеанс недействителен, сервер отправит просроченныйHTTP
откликCookie
,Например:
HTTP/1.1 200 OK
Set-Cookie: SESSION=f81d4fae-7dec-11d0-a765-00a0c91e6bf6; Expires=Thur, 1 Jan 1970 00:00:00 GMT; Secure; HttpOnly
CookieHttpSessionIdResolver
Реализация класса выглядит следующим образом:
public final class CookieHttpSessionIdResolver implements HttpSessionIdResolver {
private static final String WRITTEN_SESSION_ID_ATTR = CookieHttpSessionIdResolver.class
.getName().concat(".WRITTEN_SESSION_ID_ATTR");
// Cookie序列化策略,默认是 DefaultCookieSerializer
private CookieSerializer cookieSerializer = new DefaultCookieSerializer();
@Override
public List<String> resolveSessionIds(HttpServletRequest request) {
// 根据提供的cookieSerializer从请求中获取sessionId
return this.cookieSerializer.readCookieValues(request);
}
@Override
public void setSessionId(HttpServletRequest request, HttpServletResponse response,
String sessionId) {
if (sessionId.equals(request.getAttribute(WRITTEN_SESSION_ID_ATTR))) {
return;
}
request.setAttribute(WRITTEN_SESSION_ID_ATTR, sessionId);
// 根据提供的cookieSerializer将sessionId回写到cookie中
this.cookieSerializer
.writeCookieValue(new CookieValue(request, response, sessionId));
}
@Override
public void expireSession(HttpServletRequest request, HttpServletResponse response) {
// 这里因为是过期,所以回写的sessionId的值是“”,当请求下次进来时,就会取不到sessionId,也就意味着当前会话失效了
this.cookieSerializer.writeCookieValue(new CookieValue(request, response, ""));
}
// 指定Cookie序列化的方式
public void setCookieSerializer(CookieSerializer cookieSerializer) {
if (cookieSerializer == null) {
throw new IllegalArgumentException("cookieSerializer cannot be null");
}
this.cookieSerializer = cookieSerializer;
}
}
можно увидеть здесьCookieHttpSessionIdResolver
Операции чтения вCookieSerializer
завершить.CookieSerializer
даSpringSession
среда дляCookie
Механизм, обеспечиваемый операциями. Подробности ниже.
Анализировать sessionId на основе заголовка запроса
Класс реализации, соответствующий этой стратегии, равенHeaderHttpSessionIdResolver
, запросив заголовки изheader
разобранsessionId
. В частности, эта реализация позволит использоватьHeaderHttpSessionIdResolver(String)
чтобы указать имя заголовка. Удобные фабричные методы также можно использовать для создания имен заголовков с использованием общедоступных заголовков (например,“X-Auth-Token”
а также“authenticing-info”
) пример. При создании сеансаHTTP
Ответ будет иметь указанное имя иsessionId
значение заголовка ответа.
// 使用X-Auth-Token作为headerName
public static HeaderHttpSessionIdResolver xAuthToken() {
return new HeaderHttpSessionIdResolver(HEADER_X_AUTH_TOKEN);
}
// 使用Authentication-Info作为headerName
public static HeaderHttpSessionIdResolver authenticationInfo() {
return new HeaderHttpSessionIdResolver(HEADER_AUTHENTICATION_INFO);
}
HeaderHttpSessionIdResolver
обработкаsessionId
в сравнении сCookieHttpSessionIdResolver
Это намного проще. вокругrequest.getHeader(String)
а такжеrequest.setHeader(String,String)
Есть два способа играть.
HeaderHttpSessionIdResolver
Эта стратегия обычно используется на стороне беспроводной связи, чтобы компенсироватьCookie
поддержка сцены.
Стратегия сериализации файлов cookie
на основеCookie
РазобратьsessionId
класс реализацииCookieHttpSessionIdResolver
актуально дляCookie
Операции чтения и записи выполняются черезCookieSerializer
завершить.SpringSession
при условииCookieSerializer
Реализация интерфейса по умолчаниюDefaultCookieSerializer
, конечно, в практических приложениях мы тоже можем сами реализовать этот интерфейс, а потом передатьCookieHttpSessionIdResolver#setCookieSerializer(CookieSerializer)
метод, чтобы указать нашу собственную реализацию.
PS: Надо сказать, что мощная возможность расширения пользователя действительно
Spring
Отличный семейный стиль.
Из-за ограниченного места здесь всего два пункта:
-
CookieValue
в чем смысл существования -
DefaultCookieSerializer
Обратная записьCookie
Для конкретной реализации читайтеCookie
существуетСерия SpringSession — переписывание запросов и ответовОн был представлен в этой статье и не будет здесь повторяться. - Обработка jvm_router
CookieValue
CookieValue
даCookieSerializer
Внутренний класс в , который инкапсулируетHttpServletResponse
Напишите всю необходимую информацию. фактическиCookieValue
Нет особого смысла в существованииCookieValue
инкапсуляция для упрощения обратной записиcookie
Проблема с передачей параметров по ссылке, но нагрузки это не снижает.
Обратная запись файлов cookie
Cookie
Напишите ответ я думаю для распределенногоsession
имеет важное значение для реализацииservlet
осуществленныйHttpSession
, нам на самом деле не нужно заботиться об обратной записи, когда мы ее используемcookie
это дело, потому чтоservlet
Контейнеры все готовы. Но для распределенногоsession
Например, после перезаписиresponse
, так что вам нужно вернутьсяresponse
необходимо преобразовать текущийsession
информация черезcookie
способ подключитьresponse
возвращается клиенту - этоCookie
Обратная запись. НижеDefaultCookieSerializer
написать ответCookie
Логика, детали отмечены в коде комментариями.
@Override
public void writeCookieValue(CookieValue cookieValue) {
HttpServletRequest request = cookieValue.getRequest();
HttpServletResponse response = cookieValue.getResponse();
StringBuilder sb = new StringBuilder();
sb.append(this.cookieName).append('=');
String value = getValue(cookieValue);
if (value != null && value.length() > 0) {
validateValue(value);
sb.append(value);
}
int maxAge = getMaxAge(cookieValue);
if (maxAge > -1) {
sb.append("; Max-Age=").append(cookieValue.getCookieMaxAge());
OffsetDateTime expires = (maxAge != 0)
? OffsetDateTime.now().plusSeconds(maxAge)
: Instant.EPOCH.atOffset(ZoneOffset.UTC);
sb.append("; Expires=")
.append(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME));
}
String domain = getDomainName(request);
if (domain != null && domain.length() > 0) {
validateDomain(domain);
sb.append("; Domain=").append(domain);
}
String path = getCookiePath(request);
if (path != null && path.length() > 0) {
validatePath(path);
sb.append("; Path=").append(path);
}
if (isSecureCookie(request)) {
sb.append("; Secure");
}
if (this.useHttpOnlyCookie) {
sb.append("; HttpOnly");
}
if (this.sameSite != null) {
sb.append("; SameSite=").append(this.sameSite);
}
response.addHeader("Set-Cookie", sb.toString());
}
Вышеупомянутое состоит в том, чтобы собрать воедино строку, затем поместить ее в заголовок и, наконец, отобразить в браузере следующим образом:
Set-Cookie: SESSION=f81d4fae-7dec-11d0-a765-00a0c91e6bf6; Path=/context-root; Secure; HttpOnly
Обработка jvm_router
существуетCookie
Код чтения и записиjvmRoute
Оценка этого атрибута и соответствующая логика обработки.
1. ЧитатьCookie
фрагмент кода в
if (this.jvmRoute != null && sessionId.endsWith(this.jvmRoute)) {
sessionId = sessionId.substring(0,
sessionId.length() - this.jvmRoute.length());
}
2. Напишите ответCookie
фрагмент кода в
if (this.jvmRoute != null) {
actualCookieValue = requestedCookieValue + this.jvmRoute;
}
jvm_route
даNginx
Модуль в , роль которого заключается в передачеsession cookie
способ получитьsession
вязкость. если вcookie
а такжеurl
не вsession
, то это простоround-robin
Балансировка нагрузки. Конкретный процесс делится на следующие этапы:
- 1. Пришел первый запрос, не принеся
session
Информация,jvm_route
просто согласноround robin
Политика отправлена одномуtomcat
выше. - 2.
tomcat
добавитьsession
Информация и возвращение к клиентам. - 3. Пользователь снова запрашивает,
jvm_route
Видетьsession
Если есть имя внутреннего сервера, он перенаправляет запрос на соответствующий сервер.
По сути,jvm_route
также решитьsession
Общее решение. это иSpringSession Series — схема реализации распределенного сеансаупоминается вIP-HASH
способ чем-то похож. Опять же, проблема здесь в том, что она не может быть решена после простояsession
Проблема передачи данных в том, что они теряются при выходе из строя.
DefaultCookieSerializer
КромеCookie
После прочтения и написания есть некоторые детали, на которые стоит обратить внимание, например:Cookie
Проверка медианы,remember-me
реализация и др.