1.session是什么
當用戶在前端發起請求時,服務器會為當前用戶建立一個session,服務器將sessionId回寫給客戶端,只要用戶瀏覽器不關閉,再次請求服務器時,將sessionId傳給服務器,
服務器會根據sessionId找到與之對應的session為其服務。
如果是分布式部署時,session存儲在服務器端,下次用戶請求過來,通過負載均衡,可能會分發到其他服務器節點;所以,需要解決session一致性的問題,
使用redis來實現分布式session,個人理解是將session存放到redis中,每次請求過來時,會從redis讀取session信息
2.代碼實現
①.maven需要引入的依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> </dependency>
②.配置文件指定redis的ip和端口
spring.redis.host=172.18.66.45
spring.redis.port=6379
③.httpSession配置
package com.session.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; //maxInactiveIntervalInSeconds設置session有效時間,單位是秒;默認是30分鍾 @EnableRedisHttpSession(maxInactiveIntervalInSeconds=180) public class SessionConfig { @Value("${spring.redis.host}") private String hostName; @Value("${spring.redis.port}") private int port; @Bean public JedisConnectionFactory connectionFactory() { JedisConnectionFactory connectionFactory = new JedisConnectionFactory(); connectionFactory.setPort(port); connectionFactory.setHostName(hostName); System.out.println("獲取到的hostName是:"+hostName + ",port :"+port); return connectionFactory; } }
再實現一個controller,就可以模擬實際業務場景寫session、根據session校驗用戶是否登錄
package com.session.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class SessionController { //模擬第一次登陸時,保存session @RequestMapping(value="/login") public String login(HttpServletRequest request) { HttpSession session = request.getSession(); String str = (String) session.getAttribute("userInfo"); if(str == null || "".equals(str)) { session.setAttribute("userInfo", "mpy test session"); return "用戶登錄成功-success"; }else{ return "session中存在數據,用戶已登錄"; } } /*該方法模式登陸之后,調用業務接口
*在實際的業務場景中,可以使用攔截器,對每次請求進行判斷,校驗用戶是否登錄、session是否過期
*/ @RequestMapping(value="/getSession") public String getSession(HttpServletRequest request) { HttpSession session = request.getSession(); String str = (String) session.getAttribute("userInfo"); if(str == null || "".equals(str)) { return "session中沒有數據,請登錄"; }else{ //已登錄用戶,進行其他業務代碼的處理 System.out.println("session中的屬性是:"+str); return str; } } @RequestMapping(value="/logout") public String logout(HttpServletRequest request) { HttpSession session = request.getSession(); String str = (String) session.getAttribute("userInfo"); if(str != null && "".equals(str)) { session.invalidate(); } return "退出成功"; } }
@EnableRedisHttpSession和spring-session的實現原理還有待研究學習
具體的代碼,已經上傳至GitHub,https://github.com/mapy95/spring-session.git