基于springcloud分布式session共享

合集下载

基于springcloud分布式session共享.docx

基于springcloud分布式session共享.docx

分布式Session共享概念不同进程之间的session共享访问。

解决了分布式系统或者系统集群部署时出现的问题:web容器(如tomcat)管理的session都存放于本地内存中无法共享,用户每次访问的服务器可能都不一样,因此出现服务器不能识别用户、用户登录状态失效等。

解决方案:方案一:黏性sessionNGINX等负载均衡网关,可以通过hash映射等方式,保证相同用户的请求会转发到同一台服务器。

优点:简单高效,易实施。

缺点:存在大量请求转发到单点服务器极端情况导致负载均衡失效;单点故障导致用户session丢失。

方案二:tomcat集群session复制Tomcat提供集群环境下的session复制功能,以达到session共享。

优点:无开发工作量。

缺点:session复制会消耗大量服务器资源,只能应用于小规模的集群。

方案三:Spring session + redis(推荐)Spring session可以接管web容器的session管理,并可以将session 数据存放于redis等第三方存储。

优点:Spring boot/cloud项目无缝集成;可存储海量session数据;可以利用redis提供的持久化保证宕机恢复、服务升级重启用户session不丢失;很好的支持服务在线扩容!缺点:Spring session没有多语言版本,限制了微服务框架下不同的技术选型。

Spring boot/cloud下的使用方法:1.增加配置redis和spring session的配置spring.redis.host=127.0.0.1spring.redis.password=123456spring.redis.port=6379spring.session.store-type=redis2.创建配置类,开启注解@Configuration@EnableRedisHttpSessionpublic class UserCenterSessionConfig {@Beanpublic JedisConnectionFactory connectionFactory(){return new JedisConnectionFactory();}}Spring Cloud微服务项目中存在如下情况,导致session共享失效:1.Zuul做API网关,转发时默认禁止传递Cookie。

SpringBoot如何实现Session共享

SpringBoot如何实现Session共享

SpringBoot如何实现Session共享HttpSession,是通过Servlet容器创建并进⾏管理的,创建成功以后将会保存在内存中,这⾥将会使⽤Redis解决session共享的问题。

创建项⽬添加pom添加相关的maven<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 https:///xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!-- https:///artifact/org.springframework.boot/spring-boot-starter-data-redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.3.1.RELEASE</version></dependency><!-- https:///artifact/io.lettuce/lettuce-core --><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.0.0.M1</version></dependency><!-- https:///artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.3.0</version></dependency><!-- https:///artifact/org.springframework.session/spring-session-data-redis --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId><version>2.3.0.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>配置redis连接配置redis连接spring:redis:database: 0host: 106.53.115.12port: 6379password: 12345678jedis:pool:max-active: 8max-idle: 8max-wait: -1msmin-idle: 0创建Controller⽤来执⾏测试操作package com.example.demo;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpSession;@RestControllerpublic class HelloController {@PostMapping("/save")public String saveName(String name, HttpSession session){ session.setAttribute("name", name);return "8080";}@GetMapping("/get")public String getName(HttpSession httpSession){return httpSession.getAttribute("name").toString();}}Nginx 负载均衡mingming@xiaoming-pc:~$ sudo apt-get install nginx修改配置⽂件upstream {server 192.168.0.1:8080 weight = 1;server 192.168.0.2:8080 weight = 1;}server {listen 80;server_name localhost;location / {proxy_pass ;proxy_redirect default;}}请求分发保存数据获取数据以上就是SpringBoot 如何实现Session共享的详细内容,更多关于SpringBoot 实现Session共享的资料请关注其它相关⽂章!。

SpringBoot2.x整合Spring-Session实现Session共享功能

SpringBoot2.x整合Spring-Session实现Session共享功能

SpringBoot2.x整合Spring-Session实现Session共享功能1.前⾔发展⾄今,已经很少还存在单服务的应⽤架构,不说都使⽤分布式架构部署,⾄少也是多点⾼可⽤服务。

在多个服务器的情况下,Seession共享就是必须⾯对的问题了。

解决Session共享问题,⼤多数⼈的思路都是⽐较清晰的,将需要共享的数据存在某个公共的服务中,如缓存。

很多⼈都采⽤的Redis,⼿动将Session存在Redis,需要使⽤时,再从Redsi中读取数据。

毫⽆疑问,这种⽅案是可⾏的,只是在⼿动操作的⼯作量确实不少。

LZ在这⾥采⽤的Spring-Session来实现。

它使⽤代理过滤器,将Session操作拦截,⾃动将数据同步到Redis中,以及⾃动从Redis读取数据。

从此,操作分布式的Session就像操作单服务的Session⼀样,可以为所欲为了。

2.实践2.1 创建⼯程使⽤idea创建SpringBoot⼯程,添加组件Web、Spring Session和Redis。

我这⾥idea是2019版本,SpringBoot是2.1.6。

pom.xml⽂件<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>2.2 配置Redisspring:redis:port: 6379password: xofcO46Fyhost: 10.17.153.104server:port: 90902.3 测试代码实现package com.xiaoqiang.sessionshare.web;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession;/*** SessionShareController <br>* 〈session共享控制器〉** @author XiaoQiang* @create 2019-7-6* @since 1.0.0*/@RestController@RequestMapping(value = "/session")public class SessionShareController {@Value("${server.port}")Integer port;@GetMapping(value = "/set")public String set(HttpSession session){session.setAttribute("user","wangwq8");return String.valueOf(port);}@GetMapping(value = "get")public String get(HttpSession session){return "⽤户:"+session.getAttribute("user")+",端⼝:"+port;}}maven package打包发布到服务器服务器,过程略。

spring-session-data-redis解决session共享的问题

spring-session-data-redis解决session共享的问题

spring-session-data-redis解决session共享的问题分布式系统要做到⽤户友好,需要对⽤户的session进⾏存储,存储的⽅式有以下⼏种:1. 本地缓存2. 数据库3. ⽂件4. 缓存服务器可以看⼀些不同⽅案的优缺点1.本地机器或者本地缓存。

优点:速度快缺点:服务宕机后重启⽤户信息丢失,⽤户不优好2.数据库。

优点:技术栈简单缺点:速度慢3.⽂件。

优点:技术栈简单,速度适中缺点:⽆灾备或者灾备⽅案成本⾼4.缓存服务器。

⼀般是内存服务器,优点:速度快可以和原有技术栈契合,有现成的解决⽅案。

缺点:不明显如果使⽤java语⾔,并且缓存服务器为redis,可以使⽤开源的spring session项⽬来解决。

spring session项⽬现有三个⾃项⽬,分别是spring-session-data-redis 使⽤redis⽅式spring-session-hazelcast 使⽤hazelcast⽅式spring-session-jdbc 使⽤jdbc⽅式在这⾥我建议⼤家使⽤redis⽅式,它提供了注解式和编程式不同的⽅法。

具体如何使⽤,⽹上有很多实例,我就不赘述。

我想和⼤家⼀起深⼊内部看⼀下,spring-session项⽬的github地址为:https:///spring-projects/spring-session.git我们只看spring-session-data-redis,实现⾮常简单。

它总共只有12个类核⼼类只有⼀个RedisOperationsSessionRepository这个类内部定义了session的实现RedisSession/*** A custom implementation of {@link Session} that uses a {@link MapSession} as the* basis for its mapping. It keeps track of any attributes that have changed. When* {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession#saveDelta()}* is invoked all the attributes that have been changed will be persisted.** @author Rob Winch* @since 1.0*/final class RedisSession implements Session {private final MapSession cached;private Instant originalLastAccessTime;private Map<String, Object> delta = new HashMap<>();private boolean isNew;private String originalPrincipalName;private String originalSessionId;注意:delta 是增量 cached是存量我们来看这个RedisSession的创建销毁及修改RedisSession内部存储如下(⽰例)* <pre>* HMSET spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe creationTime 1404360000000 maxInactiveInterval 1800 lastAccessedTime 1404360000000 sessionAttr:attrName someAttrValue sessionAttr2:attrName someAttrV * EXPIRE spring:session:sessions:33fdd1b6-b496-4b33-9f7d-df96679d32fe 2100* APPEND spring:session:sessions:expires:33fdd1b6-b496-4b33-9f7d-df96679d32fe ""* EXPIRE spring:session:sessions:expires:33fdd1b6-b496-4b33-9f7d-df96679d32fe 1800* SADD spring:session:expirations:1439245080000 expires:33fdd1b6-b496-4b33-9f7d-df96679d32fe* EXPIRE spring:session:expirations1439245080000 2100* </pre>RedisSession的数据结构是Hash* <p>* Each session is stored in Redis as a* <a href="http://redis.io/topics/data-types#hashes">Hash</a>. Each session is set and* updated using the <a href="http://redis.io/commands/hmset">HMSET command</a>. An* example of how each session is stored can be seen below.* </p>RedisSession的失效* <h3>Expiration</h3>** <p>* An expiration is associated to each session using the* <a href="http://redis.io/commands/expire">EXPIRE command</a> based upon the* {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession#getMaxInactiveInterval()} * . For example:* </p>RedisSession的更新有⼀个⽐较重要的⽅法:/*** Saves any attributes that have been changed and updates the expiration of this* session.*/private void saveDelta() {String sessionId = getId();saveChangeSessionId(sessionId);if (this.delta.isEmpty()) {return;}getSessionBoundHashOperations(sessionId).putAll(this.delta);String principalSessionKey = getSessionAttrNameKey(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);String securityPrincipalSessionKey = getSessionAttrNameKey(SPRING_SECURITY_CONTEXT);if (this.delta.containsKey(principalSessionKey)|| this.delta.containsKey(securityPrincipalSessionKey)) {if (this.originalPrincipalName != null) {String originalPrincipalRedisKey = getPrincipalKey(this.originalPrincipalName);RedisOperationsSessionRepository.this.sessionRedisOperations.boundSetOps(originalPrincipalRedisKey).remove(sessionId);}String principal = PRINCIPAL_NAME_RESOLVER.resolvePrincipal(this);this.originalPrincipalName = principal;if (principal != null) {String principalRedisKey = getPrincipalKey(principal);RedisOperationsSessionRepository.this.sessionRedisOperations.boundSetOps(principalRedisKey).add(sessionId);}}this.delta = new HashMap<>(this.delta.size());Long originalExpiration = (this.originalLastAccessTime != null)this.originalLastAccessTime.plus(getMaxInactiveInterval()).toEpochMilli(): null;RedisOperationsSessionRepository.this.expirationPolicy.onExpirationUpdated(originalExpiration, this);}⼩结:1.session是键值对形式的,对应redis的数据结构hash2.session的存储形式使⽤redis⾮常⽅便。

使用SpringSession做分布式会话管理

使用SpringSession做分布式会话管理

使⽤SpringSession做分布式会话管理 在Web项⽬开发中,会话管理是⼀个很重要的部分,⽤于存储与⽤户相关的数据。

通常是由符合session规范的容器来负责存储管理,也就是⼀旦容器关闭,重启会导致会话失效。

因此打造⼀个⾼可⽤性的系统,必须将session管理从容器中独⽴出来。

⽽这实现⽅案有很多种,下⾯简单介绍下: 第⼀种是使⽤容器扩展来实现,⼤家⽐较容易接受的是通过容器插件来实现,⽐如基于Tomcat的,基于Jetty的等等。

好处是对项⽬来说是透明的,⽆需改动代码。

不过前者⽬前还不⽀持Tomcat 8,或者说不太完善。

个⼈觉得由于过于依赖容器,⼀旦容器升级或者更换意味着⼜得从新来过。

并且代码不在项⽬中,对开发者来说维护也是个问题。

第⼆种是⾃⼰写⼀套会话管理的⼯具类,包括Session管理和Cookie管理,在需要使⽤会话的时候都从⾃⼰的⼯具类中获取,⽽⼯具类后端存储可以放到Redis中。

很显然这个⽅案灵活性最⼤,但开发需要⼀些额外的时间。

并且系统中存在两套Session⽅案,很容易弄错⽽导致取不到数据。

第三种是使⽤框架的会话管理⼯具,也就是本⽂要说的,可以理解是替换了Servlet那⼀套会话管理,既不依赖容器,⼜不需要改动代码,并且是⽤了spring-data-redis那⼀套连接池,可以说是最完美的解决⽅案。

当然,前提是项⽬要使⽤Spring Framework才⾏。

这⾥简单记录下整合的过程: 如果项⽬之前没有整合过spring-data-redis的话,这⼀步需要先做,在maven中添加这两个依赖:1 <dependency>2 <groupId>org.springframework.data</groupId>3 <artifactId>spring-data-redis</artifactId>4 <version>1.5.2.RELEASE</version>5 </dependency>6 <dependency>7 <groupId>org.springframework.session</groupId>8 <artifactId>spring-session</artifactId>9 <version>1.0.2.RELEASE</version>10 </dependency> 再在applicationContext.xml中添加以下bean,⽤于定义redis的连接池和初始化redis模版操作类,⾃⾏替换其中的相关变量。

spring-session实现分布式集群session的共享

spring-session实现分布式集群session的共享

spring-session实现分布式集群session的共享前⾔ HttpSession是通过Servlet容器创建和管理的,像Tomcat/Jetty都是保存在内存中的。

但是我们把应⽤搭建成分布式的集群,然后利⽤LVS或Nginx做负载均衡,那么来⾃同⼀⽤户的Http请求将有可能被分发到多个不同的应⽤中。

那问题来了,如何保证不同的应⽤能够共享同⼀份session数据呢?最简单的想法,就是把session数据保存到内存以外的⼀个统⼀的地⽅,例如Memcached/Redis等数据库中。

那问题⼜来了,如何替换掉Servlet容器创建和管理的HttpSession的实现呢? 1、利⽤Servlet容器提供的插件功能,⾃定义HttpSession的创建和管理策略,并通过配置的⽅式替换掉默认的策略。

这⽅⾯其实早就有开源项⽬了,例如memcached-session-manager(可以参考),以及tomcat-redis-session-manager。

不过这种⽅式有个缺点,就是需要耦合Tomcat/Jetty等Servlet容器的代码。

2、设计⼀个Filter,利⽤HttpServletRequestWrapper,实现⾃⼰的getSession()⽅法,接管创建和管理Session数据的⼯作。

spring-session就是通过这样的思路实现的。

参考 本博客不涉及session解释,关于session⼤家⾃⾏去查资料;关于spring-session的相关概念⼤家可以去spring官⽹查阅(http://projects.spring.io/spring-session/)。

单机应⽤ 我们先来看下单机应⽤,应⽤很简单,就是在session中设置变量,然后获取这些设置的变量进⾏展⽰,具体代码如下 pom.xml:<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.yzb.lee</groupId><artifactId>spring-session</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>spring-session Maven Webapp</name><url></url><properties><piler.source>1.8</piler.source><piler.target>1.8</piler.target></properties><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency></dependencies><build><finalName>spring-session</finalName></build></project>View Code web.xml<?xml version="1.0" encoding="UTF-8"?><web-app><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>session</servlet-name><servlet-class>com.yzb.lee.servlet.SessionServlet</servlet-class></servlet><servlet-mapping><servlet-name>session</servlet-name><url-pattern>/session</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list></web-app>View Code SessionServlet.javapackage com.yzb.lee.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class SessionServlet extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String attributeName = req.getParameter("attributeName");String attributeValue = req.getParameter("attributeValue");req.getSession().setAttribute(attributeName, attributeValue);resp.sendRedirect(req.getContextPath() + "/");}}View Code index.jsp<%@ taglib prefix="c" uri="/jsp/jstl/core" %><%@ page isELIgnored="false" %><!DOCTYPE html><html lang="en"><head><title>Session Attributes</title></head><body><div class="container"><h1>Description</h1><p>This application demonstrates how to use a Redis instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way <h1>Try it</h1><form class="form-inline" role="form" action="./session" method="post"><label for="attributeName">Attribute Name</label><input id="attributeName" type="text" name="attributeName"/><label for="attributeValue">Attribute Value</label><input id="attributeValue" type="text" name="attributeValue"/><input type="submit" value="Set Attribute"/></form><hr/><table class="table table-striped"><thead><tr><th>Attribute Name</th><th>Attribute Value</th></tr></thead><tbody><c:forEach items="${sessionScope}" var="attr"><tr><td><c:out value="${attr.key}"/></td><td><c:out value="${attr.value}"/></td></tr></c:forEach></tbody></table></div></body></html>View Code 整个项⽬结构⾮常简单,如下如 本地运⾏起来,效果如下 ⽕狐浏览器与360浏览器代表不同的⽤户,各⾃都能获取各⾃session中的设置的全部变量,很正常,没⽑病。

Session机制详解及分布式中Session共享解决方案

Session机制详解及分布式中Session共享解决方案

Session机制详解及分布式中Session共享解决⽅案引⽤⽹址:⼀、为什么要产⽣Session http协议本⾝是⽆状态的,客户端只需要向服务器请求下载内容,客户端和服务器都不记录彼此的历史信息,每⼀次请求都是独⽴的。

为什么是⽆状态的呢?因为浏览器与服务器是使⽤socke套接字进⾏通信,服务器将请求结果返回给浏览器之后,会关闭当前的socket 链接,⽽且服务器也会在处理页⾯完毕之后销毁页⾯对象。

然⽽在Web应⽤的很多场景下需要维护⽤户状态才能正常⼯作(是否登录等),或者说提供便捷(记住密码,浏览历史等),状态的保持就是⼀个很重要的功能。

因此在web应⽤开发⾥就出现了保持http链接状态的技术:⼀个是cookie技术,另⼀种是session技术。

⼆、Session有什么作⽤,如何产⽣并发挥作⽤ 要明⽩Session就必须要弄明⽩什么是Cookie,以及Cookie和Session的关系。

1、什么是Cookie Cookie技术是http状态保持在客户端的解决⽅案,Cookie就是由服务器发给客户端的特殊信息,⽽这些信息以⽂本⽂件的⽅式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。

2、Cookie的产⽣ 当⽤户⾸次使⽤浏览器访问⼀个⽀持Cookie的⽹站的时候,⽤户会提供包括⽤户名在内的个⼈信息并且提交⾄服务器;接着,服务器在向客户端回传相应的超⽂本的同时也会发回这些个⼈信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,⽽是存放于HTTP响应头(Response Header);当客户端浏览器接收到来⾃服务器的响应之后,浏览器会将这些信息存放在⼀个统⼀的位置。

存储在硬盘上的cookie 不可以在不同的浏览器间共享,可以在同⼀浏览器的不同进程间共享,⽐如两个IE窗⼝。

这是因为每中浏览器存储cookie的位置不⼀样,⽐如 Chrome下的cookie放在:C:\Users\sharexie\AppData\Local\Google\Chrome\User Data\Default\Cache Firefox下的cookie放在:C:\Users\sharexie\AppData\Roaming\Mozilla\Firefox\Profiles\tq2hit6m.default\cookies.sqlite (倒数第⼆个⽂件名是随机的⽂件名字) Ie下的cookie放在:C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Cookies 3、Cookie的内容、作⽤域以及有效期 cookie的内容主要包括:名字,值,过期时间,路径和域。

分布式session一致性问题

分布式session一致性问题

分布式session⼀致性问题1.分布式session⼀致性:指服务器集群情况下session共享的问题。

2.session的作⽤:保存服务器(tomcat)与客户端(浏览器)整个通讯的会话基本信息。

3.session应⽤场景:记录⽤户信息。

登录场景(账号密码登陆成功之后,获取到userid,存放在session中,下次登录的时候直接从session中获取⽤户信息)、防⽌表单重复提交。

session可以理解为本地jvm缓存,session存放在服务器端,返回sessionid给客户端,客户端下⼀次请求根据sessionid去服务器端获取⽤户信息。

session原理:session存放在哪⾥?服务器端浏览器关闭了,session会失效吗?不会失效。

第⼀次请求:客户端向服务器端发送⼀个请求,服务器接收到客户端的请求,会创建⼀个session,使⽤响应头返回给客户端⼀个sessionid,浏览器获取到sessionid之后存放在本地。

第⼆次请求:客户端读取本地的sessionid存放在请求头中,服务器端从请求头中获取到对应的sessionid,使⽤sessionid在服务器本地查询对应的信息。

//默认创建⼀个session,默认值为true。

//设置为true情况下,客户端使⽤对应的sessionid查询不到的对应的session,则会创建⼀个新的session。

如果查到则复⽤。

//设置为false情况下,客户端使⽤对应的sessionid查询不到对应的session的时候,不会创建session。

HttpSession session = request.getSession();System.out.println("存⼊session信息,sessionid:" + session.getId() + ",value:" + value + ",serverPort:" + serverPort);session.setAttribute("name", value);session 分为sessionid和sessionvaluesession 跟 token⾮常相似。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档