返回顶部
首页 > 资讯 > 精选 >spring-session如何实现
  • 836
分享到

spring-session如何实现

springsession 2023-05-30 20:05:06 836人浏览 薄情痞子
摘要

小编给大家分享一下spring-session如何实现,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一:spring-session介绍1.简介session一直都是我们做集群时需要解决的一个难题,过去我们可以从serlv

小编给大家分享一下spring-session如何实现,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

一:spring-session介绍

1.简介

session一直都是我们做集群时需要解决的一个难题,过去我们可以从serlvet容器上解决,比如开源servlet容器-Tomcat提供的tomcat-redis-session-manager、memcached-session-manager。

或者通过Nginx之类的负载均衡做ip_hash,路由到特定的服务器上..

但是这两种办法都存在弊端。

spring-session是spring旗下的一个项目,把servlet容器实现的httpsession替换为spring-session,专注于解决 session管理问题。可简单快速且无缝的集成到我们的应用中。

支持功能

1)轻易把session存储到第三方存储容器,框架提供了RedisJVM的map、monGo、gemfire、hazelcast、jdbc等多种存储session的容器的方式。

2)同一个浏览器同一个网站,支持多个session问题。

3)Restfulapi,不依赖于cookie。可通过header来传递jessionID

4)websocket和spring-session结合,同步生命周期管理。

集成方式

集成方式非常简单,直接看官网的samplesandguide。Http://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/HTML5/

主要分为以下几个集成步骤:

1)引入依赖jar

2)注解方式或者xml方式配置特定存储容器的存储方式,如redis的xml配置方式

<context:annotation-config/>  <beanclass="org.springframework.session.data.redis.config.annotation.WEB.http.RedisHttpSessionConfiguration"/>   <beanclass="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>

3)xml方式配置 web.xml ,配置 springSessionFilter到 filter chain中

<filter>     <filter-name>springSessionRepositoryFilter</filter-name>     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    </filter>    <filter-mapping>     <filter-name>springSessionRepositoryFilter</filter-name>     <url-pattern>public class SessionRepositoryFilter<S extends ExpiringSession>    extends OncePerRequestFilter {    private final SessionRepository<S> sessionRepository;  private ServletContext servletContext;    private MultiHttpSessionStrategy httpSessionStrategy = new CookieHttpSessionStrategy();  public SessionRepositoryFilter(SessionRepository<S> sessionRepository) {    if (sessionRepository == null) {      throw new IllegalArgumentException("sessionRepository cannot be null");    }    this.sessionRepository = sessionRepository;  }  public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) {    if (httpSessionStrategy == null) {      throw new IllegalArgumentException("httpSessionStrategy cannot be null");    }        this.httpSessionStrategy = new MultiHttpSessionStrategyAdapter(        httpSessionStrategy);  }  public void setHttpSessionStrategy(MultiHttpSessionStrategy httpSessionStrategy) {    if (httpSessionStrategy == null) {      throw new IllegalArgumentException("httpSessionStrategy cannot be null");    }    this.httpSessionStrategy = httpSessionStrategy;  }     @Override  protected void doFilterInternal(HttpServletRequest request,      HttpServletResponse response, FilterChain filterChain)      throws ServletException, IOException {    request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);            SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(        request, response, this.servletContext);    SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(        wrappedRequest, response);    HttpServletRequest strategyRequest = this.httpSessionStrategy        .wrapRequest(wrappedRequest, wrappedResponse);    HttpServletResponse strategyResponse = this.httpSessionStrategy        .wrapResponse(wrappedRequest, wrappedResponse);    try {              filterChain.doFilter(strategyRequest, strategyResponse);    }    finally {      wrappedRequest.commitSession();    }  }  public void setServletContext(ServletContext servletContext) {    this.servletContext = servletContext;  }    private final class SessionRepositoryResponseWrapper      extends OnCommittedResponseWrapper {    private final SessionRepositoryRequestWrapper request;    SessionRepositoryResponseWrapper(SessionRepositoryRequestWrapper request,        HttpServletResponse response) {      super(response);      if (request == null) {        throw new IllegalArgumentException("request cannot be null");      }      this.request = request;    }         @Override    protected void onResponseCommitted() {      this.request.commitSession();    }  }    private final class SessionRepositoryRequestWrapper      extends HttpServletRequestWrapper {    private Boolean requestedSessionIdValid;    private boolean requestedSessionInvalidated;    private final HttpServletResponse response;    private final ServletContext servletContext;    private SessionRepositoryRequestWrapper(HttpServletRequest request,        HttpServletResponse response, ServletContext servletContext) {      super(request);      this.response = response;      this.servletContext = servletContext;    }        private void commitSession() {      HttpSessionWrapper wrappedSession = getCurrentSession();      if (wrappedSession == null) {          // session失效,删除cookie或者header        if (isInvalidateClientSession()) {          SessionRepositoryFilter.this.httpSessionStrategy              .onInvalidateSession(this, this.response);        }      }      else {        S session = wrappedSession.getSession();        SessionRepositoryFilter.this.sessionRepository.save(session);        if (!isRequestedSessionIdValid()            || !session.getId().equals(getRequestedSessionId())) {        // 把cookie或者header写回给浏览器保存         SessionRepositoryFilter.this.httpSessionStrategy.onNewSession(session,              this, this.response);        }      }    }    @SuppressWarnings("unchecked")    private HttpSessionWrapper getCurrentSession() {      return (HttpSessionWrapper) getAttribute(CURRENT_SESSION_ATTR);    }    private void setCurrentSession(HttpSessionWrapper currentSession) {      if (currentSession == null) {        removeAttribute(CURRENT_SESSION_ATTR);      }      else {        setAttribute(CURRENT_SESSION_ATTR, currentSession);      }    }    @SuppressWarnings("unused")    public String changeSessionId() {      HttpSession session = getSession(false);      if (session == null) {        throw new IllegalStateException(            "Cannot change session ID. There is no session associated with this request.");      }      // eagerly get session attributes in case implementation lazily loads them      Map<String, Object> attrs = new HashMap<String, Object>();      Enumeration<String> iAttrNames = session.getAttributeNames();      while (iAttrNames.hasMoreElements()) {        String attrName = iAttrNames.nextElement();        Object value = session.getAttribute(attrName);        attrs.put(attrName, value);      }      SessionRepositoryFilter.this.sessionRepository.delete(session.getId());      HttpSessionWrapper original = getCurrentSession();      setCurrentSession(null);      HttpSessionWrapper newSession = getSession();      original.setSession(newSession.getSession());      newSession.setMaxInactiveInterval(session.getMaxInactiveInterval());      for (Map.Entry<String, Object> attr : attrs.entrySet()) {        String attrName = attr.geTKEy();        Object attrValue = attr.getValue();        newSession.setAttribute(attrName, attrValue);      }      return newSession.getId();    }    // 判断session是否有效    @Override    public boolean isRequestedSessionIdValid() {      if (this.requestedSessionIdValid == null) {        String sessionId = getRequestedSessionId();        S session = sessionId == null ? null : getSession(sessionId);        return isRequestedSessionIdValid(session);      }      return this.requestedSessionIdValid;    }    private boolean isRequestedSessionIdValid(S session) {      if (this.requestedSessionIdValid == null) {        this.requestedSessionIdValid = session != null;      }      return this.requestedSessionIdValid;    }    private boolean isInvalidateClientSession() {      return getCurrentSession() == null && this.requestedSessionInvalidated;    }    private S getSession(String sessionId) {       // 从session存储容器中根据sessionID获取session      S session = SessionRepositoryFilter.this.sessionRepository          .getSession(sessionId);      if (session == null) {        return null;      }      // 设置sesison的最后访问时间,以防过期      session.setLastAccessedTime(System.currentTimeMillis());      return session;    }         @Override    public HttpSessionWrapper getSession(boolean create) {      //快速获取session,可以理解为一级缓存、二级缓存这种关系      HttpSessionWrapper currentSession = getCurrentSession();      if (currentSession != null) {        return currentSession;      }      //从httpSessionStratge里面根据cookie或者header获取sessionID      String requestedSessionId = getRequestedSessionId();      if (requestedSessionId != null          && getAttribute(INVALID_SESSION_ID_ATTR) == null) {                                                   //从存储容器获取session以及设置当次初始化属性                              S session = getSession(requestedSessionId);        if (session != null) {          this.requestedSessionIdValid = true;          currentSession = new HttpSessionWrapper(session, getServletContext());          currentSession.setNew(false);          setCurrentSession(currentSession);          return currentSession;        }        else {          if (SESSION_LOGGER.isDebugEnabled()) {            SESSION_LOGGER.debug(                "No session found by id: Caching result for getSession(false) for this HttpServletRequest.");          }          setAttribute(INVALID_SESSION_ID_ATTR, "true");        }      }      if (!create) {        return null;      }      if (SESSION_LOGGER.isDebugEnabled()) {        SESSION_LOGGER.debug(            "A new session was created. To help you troubleshoot where the session was created we provided a StackTrace (this is not an error). You can prevent this from appearing by disabling DEBUG logging for "                + SESSION_LOGGER_NAME,            new RuntimeException(                "For debugging purposes only (not an error)"));      }      // 如果该浏览器或者其他http访问者是初次访问服务器,则为他创建个新的session      S session = SessionRepositoryFilter.this.sessionRepository.createSession();      session.setLastAccessedTime(System.currentTimeMillis());      currentSession = new HttpSessionWrapper(session, getServletContext());      setCurrentSession(currentSession);      return currentSession;    }    @Override    public ServletContext getServletContext() {      if (this.servletContext != null) {        return this.servletContext;      }      // Servlet 3.0+      return super.getServletContext();    }    @Override    public HttpSessionWrapper getSession() {      return getSession(true);    }    @Override    public String getRequestedSessionId() {      return SessionRepositoryFilter.this.httpSessionStrategy          .getRequestedSessionId(this);    }        private final class HttpSessionWrapper extends ExpiringSessionHttpSession<S> {      HttpSessionWrapper(S session, ServletContext servletContext) {        super(session, servletContext);      }      @Override      public void invalidate() {        super.invalidate();        SessionRepositoryRequestWrapper.this.requestedSessionInvalidated = true;        setCurrentSession(null);        SessionRepositoryFilter.this.sessionRepository.delete(getId());      }    }  }}

看完了这篇文章,相信你对“spring-session如何实现”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!

--结束END--

本文标题: spring-session如何实现

本文链接: https://lsjlt.com/news/220756.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • spring-session如何实现
    小编给大家分享一下spring-session如何实现,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一:spring-session介绍1.简介session一直都是我们做集群时需要解决的一个难题,过去我们可以从serlv...
    99+
    2023-05-30
    spring session
  • Spring session如何实现Session共享
    这篇文章主要介绍“Spring session如何实现Session共享”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Spring session如何实现Session共享”文章...
    99+
    2023-07-06
  • 在Spring-Session使用Redis如何实现共享session
    这期内容当中小编将会给大家带来有关在Spring-Session使用Redis如何实现共享session,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、添加依赖<dependency> &l...
    99+
    2023-05-31
    spring session redis
  • Spring Boot/Spring Session/Redis的分布式Session共享如何解决
    本篇文章为大家展示了Spring Boot/Spring Session/Redis的分布式Session共享如何解决,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。分布式Web网站一般都会碰到集群s...
    99+
    2023-05-31
    springboot spring session redis
  • SpringBoot下如何实现session
    这篇文章主要介绍了SpringBoot下如何实现session的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot下如何实现session文章都会有所收获,下面我们一起来看看吧。相关概念1.HTT...
    99+
    2023-06-29
  • Redis如何实现Session共享
    这篇文章运用简单易懂的例子给大家介绍Redis如何实现Session共享,代码非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Redis实现Session共享这几天在做session共享这么一...
    99+
    2024-04-02
  • redis如何实现session同步
    Redis可以通过以下几种方式实现session同步:1. 使用Redis Cluster:Redis Cluster是Redis自...
    99+
    2023-08-30
    redis session
  • 在Spring项目中实现分布式session
    在Spring项目中实现分布式session?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1. 引入Spring Session maven依赖<!-- spring s...
    99+
    2023-05-31
    分布式 session spring
  • spring boot与redis 实现session共享教程
    如果大家对spring boot不是很了解,大家可以参考下面两篇文章。Spring Boot 快速入门教程Spring Boot 快速入门指南这次带来的是spring boot + redis 实现session共享的教程。在spring ...
    99+
    2023-05-31
    spring boot redis
  • Spring Boot项目利用Redis实现session管理实例
    在现代网络服务中,session(会话)不得不说是非常重要也是一定要实现的概念,因此在web后台开发中,对session的管理和维护是必须要实现的组件。这篇文章主要是介绍如何在Spring Boot项目中加入redis来实现对session...
    99+
    2023-05-31
    spring boot redis
  • JavaScript如何控制Session的实现原理
    本篇内容主要讲解“JavaScript如何控制Session的实现原理”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript如何控制Session的...
    99+
    2024-04-02
  • Spring Boot如何实现WebSocket
    本篇内容介绍了“Spring Boot如何实现WebSocket”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是 WebSoc...
    99+
    2023-06-30
  • 怎么在Spring Boot中利用Redis实现session共享
    本篇文章给大家分享的是有关怎么在Spring Boot中利用Redis实现session共享,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。引入spring-boot-start...
    99+
    2023-05-30
    springboot session redis
  • SpringBoot 整合 Spring-Session 实现分布式会话项目实战
    目录一、配置及开发二、测试三、Spring-Session 的缺点文章参考:Spring 提供了处理分布式会话的解决方案:Spring-Session。Spring-Session ...
    99+
    2024-04-02
  • Cloud Foundry Session Affinity(Sticky Session)的实现
    会话保持(Session Affinity),有时又称粘滞会话(Sticky Sessions), 是负载均衡领域设计需要着力解决的重要问题之一,也是一个相对比较复杂的问题。会话保持是指在负载均衡器上的一种机制,在完成负载均衡任务的同时,还...
    99+
    2023-06-03
  • Spring session如何获取当前账户登录数
    今天小编给大家分享一下Spring session如何获取当前账户登录数的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
    99+
    2023-07-05
  • Session实现原理
    HTTP协议 ( http://www.w3.org/Protocols/ )是“一次性单向”协议。 服务端不能主动连接客户端,只能被动等待并答复客户端请求。客户端连接服务端,发出一个HTTP Request,服务端处理请求,并且返回一个H...
    99+
    2023-06-03
  • 如何使用MongoDB来实现web.py的session存储
    这篇文章将为大家详细讲解有关如何使用MongoDB来实现web.py的session存储,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。  web.py是一个python的...
    99+
    2024-04-02
  • 如何基于Session实现短信登录功能
    目录一、基于Session实现登录1.1 业务流程图二、发送短信验证码2.1 发送短信请求方式及参数说明三、登录功能  3.1  短信验证的请求方式及路径3.2  业务层代码实现用户登录3....
    99+
    2024-04-02
  • 如何通过Memcached实现session server会话保持
    今天小编给大家分享一下如何通过Memcached实现session server会话保持的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了...
    99+
    2023-06-27
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作