cookie、spring-session框架存入学生登陆后的学生信息

xiaoxiao2025-08-30  11

下面的Cookie代码用到了分布式redis

 

cookie在setPath时

 

domain="happymmall.com" A.happymmall.com cookie:domain=A.happymmall.com;path="/" B.happymmall.com cookie:domain=B.happymmall.com;path="/" A.happymmall.com/test/cc cookie:domain=A.happymmall.com;path="/test/cc" A.happymmall.com/test/dd cookie:domain=A.happymmall.com;path="/test/dd" A.happymmall.com/test cookie:domain=A.happymmall.com;path="/test

 

CookieUtil

@Slf4j public class CookieUtil { private final static String COOKIE_DOMAIN = "mmall.com"; private final static String COOKIE_NAME = "mmall_login_token"; public static String readLoginToken(HttpServletRequest request){ Cookie[] cks = request.getCookies(); if(cks != null){ for(Cookie ck : cks){ log.info("read cookieName:{},cookieValue:{}",ck.getName(),ck.getValue()); if(StringUtils.equals(ck.getName(),COOKIE_NAME)){ log.info("return cookieName:{},cookieValue:{}",ck.getName(),ck.getValue()); return ck.getValue(); } } } return null; } public static void writeLoginToken(HttpServletResponse response, String token){ Cookie ck = new Cookie(COOKIE_NAME,token); ck.setDomain(COOKIE_DOMAIN); ck.setPath("/");//代表设置在根目录 ck.setHttpOnly(true); //单位是秒。 //如果这个maxage不设置的话,cookie就不会写入硬盘,而是写在内存。只在当前页面有效。 ck.setMaxAge(60 * 60 * 24 * 365);//如果是-1,代表永久 log.info("write cookieName:{},cookieValue:{}",ck.getName(),ck.getValue()); response.addCookie(ck); } public static void delLoginToken(HttpServletRequest request,HttpServletResponse response){ Cookie[] cks = request.getCookies(); if(cks != null){ for(Cookie ck : cks){ if(StringUtils.equals(ck.getName(),COOKIE_NAME)){ ck.setDomain(COOKIE_DOMAIN); ck.setPath("/"); ck.setMaxAge(0);//设置成0,代表删除此cookie。 log.info("del cookieName:{},cookieValue:{}",ck.getName(),ck.getValue()); response.addCookie(ck); return; } } } } }

 

这时候,坑就来了。。。。

你可能在别的博客中看到过这样的代码

 

区别就在多了一个点

当项目中使用单点登录功能时,通常会使用cookie进行信息的保存,这样就可以在多个子域名上存取用户信息。

三个domain分别为test.com   cml.test.com   b.test.com这三个域名下的cookie是需要互相访问的。这时会在response上写入cookie信息

如果你使用带 . 的域名,这样写在tomcat8.0是没问题的,二级三级域名可以共享cookie信息。但是把它放到tomcat8.5上就报错了 (java.lang.IllegalArgumentException: An invalid domain [.test.com] was specified for this cookie)

解决方法:

 

1.指定完整的domain信息,但是这样单点登录就会有问题了

        cookie.setDomain("cml.test.com");

2.设置为一级域名(推荐)

        cookie.setDomain("test.com");

 

在web.xml中添加如下代码,重置session时间

 

<filter> <filter-name>sessionExpireFilter</filter-name> <filter-class>com.mmall.controller.common.SessionExpireFilter</filter-class> </filter> <filter-mapping> <filter-name>sessionExpireFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping>

 

SessionExpireFilter重置session时间

public class SessionExpireFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest; String loginToken = CookieUtil.readLoginToken(httpServletRequest); if(StringUtils.isNotEmpty(loginToken)){ //判断logintoken是否为空或者""; //如果不为空的话,符合条件,继续拿user信息 String userJsonStr = RedisShardedPoolUtil.get(loginToken); User user = JsonUtil.string2Obj(userJsonStr,User.class); if(user != null){ //如果user不为空,则重置session的时间,即调用expire命令 RedisShardedPoolUtil.expire(loginToken, Const.RedisCacheExtime.REDIS_SESSION_EXTIME); } } filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { } }

在代码中的使用为

登陆:

CookieUtil.writeLoginToken(httpServletResponse,session.getId()); RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()),Const.RedisCacheExtime.REDIS_SESSION_EXTIME);

 

登出:

String loginToken = CookieUtil.readLoginToken(httpServletRequest); CookieUtil.delLoginToken(httpServletRequest,httpServletResponse); RedisShardedPoolUtil.del(loginToken);

 

判断用户是否登陆:

String loginToken = CookieUtil.readLoginToken(httpServletRequest); if(StringUtils.isEmpty(loginToken)){ return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息"); } String userJsonStr = RedisShardedPoolUtil.get(loginToken); User user = JsonUtil.string2Obj(userJsonStr,User.class); if(user == null){ return ServerResponse.createByErrorMessage("用户未登录"); }

 

 

 

 

spring-session框架

 

在pom.xml中添加

<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>1.2.0.RELEASE</version> </dependency>

 

在web.xml中添加如下代码

<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>*.do</url-pattern> </filter-mapping>

 

applicationContext-spring-session.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <property name="maxInactiveIntervalInSeconds" value="1800" /> </bean> <bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer"> <property name="domainName" value="mmall.com" /> <property name="useHttpOnlyCookie" value="true" /> <property name="cookiePath" value="/" /> <property name="cookieMaxAge" value="31536000" /> </bean> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="20"/> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="127.0.0.1" /> <property name="port" value="6379" /> <property name="poolConfig" ref="jedisPoolConfig" /> </bean> </beans>

 

使用方式对比:

@Controller @RequestMapping("/user/springsession/") public class UserSpringSessionController { @Autowired private IUserService iUserService; /** * 用户登录 * @param username * @param password * @param session * @return */ @RequestMapping(value = "login.do",method = RequestMethod.GET) @ResponseBody public ServerResponse<User> login(String username, String password, HttpSession session, HttpServletResponse httpServletResponse){ //测试全局异常 // int i = 0; // int j = 666/i; ServerResponse<User> response = iUserService.login(username,password); if(response.isSuccess()){ session.setAttribute(Const.CURRENT_USER,response.getData()); // CookieUtil.writeLoginToken(httpServletResponse,session.getId()); // RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()),Const.RedisCacheExtime.REDIS_SESSION_EXTIME); } return response; } @RequestMapping(value = "logout.do",method = RequestMethod.GET) @ResponseBody public ServerResponse<String> logout(HttpSession session,HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse){ // String loginToken = CookieUtil.readLoginToken(httpServletRequest); // CookieUtil.delLoginToken(httpServletRequest,httpServletResponse); // RedisShardedPoolUtil.del(loginToken); session.removeAttribute(Const.CURRENT_USER); return ServerResponse.createBySuccess(); } @RequestMapping(value = "get_user_info.do",method = RequestMethod.GET) @ResponseBody public ServerResponse<User> getUserInfo(HttpSession session,HttpServletRequest httpServletRequest){ // String loginToken = CookieUtil.readLoginToken(httpServletRequest); // if(StringUtils.isEmpty(loginToken)){ // return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息"); // } // String userJsonStr = RedisShardedPoolUtil.get(loginToken); // User user = JsonUtil.string2Obj(userJsonStr,User.class); User user = (User)session.getAttribute(Const.CURRENT_USER); if(user != null){ return ServerResponse.createBySuccess(user); } return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息"); } }

 

转载请注明原文地址: https://www.6miu.com/read-5035467.html

最新回复(0)