Spring mvc 分步式session的实例详解

所属分类: 网络编程 / JSP编程 阅读数: 2007
收藏 0 赞 0 分享

Spring mvc 分步式session的实例详解

Session代表服务器与浏览器的一次会话过程,它的信息是保存在服务器端的。在Servlet中,session指的是HttpSession类的对象。服务器在创建session后,会把sessionid以cookie的形式回写给客户端。只要客户端的浏览器不关,每一次访问服务器都会带上这个sessionid。这样就可以在每次请求的时候获取到session的信息。

下面以spring MVC以例来说明如果创建分步式session.

1、login – 登录页

login表示用户跳转到登录页面,这个时候可以生成唯一key为sessionid的sesssionid。保存sessionid到response中,当用户真正登录的时候获取sessionid,因为是分步式所以统一的管理sessionid,把它保存在Redis缓存中。

public class LoginController{

  private static final String SESSION_ID_COOKIE = "sessionId";

  @Autowired
  private RedisClient client;

  @RequestMapping(value="/login/index")
  public ModelAndView login(HttpServletRequest request, HttpServletResponse response){
    ModelAndView modelAndView = new ModelAndView("/login");
    String sessionId = CookieUtils.getCookieValue(request, SESSION_ID_COOKIE);
    if(StringUtils.isEmptyOrNull(sessionId)) {
      sessionId = getUniqueSessionId();
      addCookie(response, SESSION_ID_COOKIE, sessionId);
    }
    // 其它业务相关信息

    return modelAndView;
  }

  // 添加cookie到response
  private void addCookie(HttpServletResponse response, String cookieName, String cookieValue) {
    Cookie cookie = new Cookie(cookieName, cookieValue);
    cookie.setPath("/");
    cookie.setMaxAge(-1);
    response.addCookie(cookie);
  }

  // 获取唯一sessionid
  private String getUniqueSessionId() {
    String sessionId = "";
    while(true) {
      String uuid = UUID.randomUUID().toString();
      String[] jsessionIdArray = uuid.split("-");
      StringBuilder jsessionIdBuilder = new StringBuilder();
      for(String str: jsessionIdArray) {
        jsessionIdBuilder.append(str);
      }
      sessionId = jsessionIdBuilder.toString();
      if(!redisClient.exists(sessionId)) {
        break;
      }
    }
    return sessionId;
  }
}

2、authenticate – 身份认证/登录

用户输入用户名密码,需要在后台进行登录。此时可以从cookie中获取到sessionid,然后再从redis里面获取到它的值sessionidvalue。并且把需要保存的session信息以sessionidvalue为key,保存在redis里面。

public class LoginController{

  private static final String SESSION_ID_COOKIE = "sessionId";

  private static final Integer REDIS_SESSION_TIME_SECONDS = 2 * 60 * 60;

  @Autowired
  private RedisClient client;

  @RequestMapping(value="/authenticate")
  @ResponseBody
  public ResponseInfo login(String username, String password, HttpServletRequest request){
    ResponseInfo<Object> responseInfo = new ResponseInfo<Object>();
    try {
      Account account = authenticate(username, password);

      saveSession(account);
      responseInfo.setStatus(0);
      responseInfo.setMessage("success");
    } catch(Exceptioin e){
      responseInfo.setStatus(1);
      responseInfo.setMessage("服务器正忙,请稍候重试")
    }

    return responseInfo;
  }

  // 保存session信息
  private void saveSession(Account account) {
    String sessionId = CookieUtils.getCookieValue(request, SESSION_ID_COOKIE);
    redisClient.set(sessionId, account);
    redisClient.expire(sessionId, REDIS_SESSION_TIME_SECONDS);
  }
}

3、logout – 登出

当用户选择退出系统时,需要把页面跳转到登录页面也就是第一步并且需要删除在redis里面的session信息以及在Cookie里面的sessionid.

public class LoginController{

  private static final String SESSION_ID_COOKIE = "sessionId";

  @Autowired
  private RedisClient client;

  @RequestMapping(value="/logout", method = RequestMethod.GET)
  public void logout(HttpServletRequest request, HttpServletResponse response) {
    // 获取到重定向位置也就是登录页
    String redirectUrl = this.getLoginPageRedirectUrl(request);

    clearSession(request);
    clearSessionCookie(request, response);
    response.sendRedirect(redirectUrl);
  }

  // 删除session在redis里面的信息
  private void clearSession(HttpServletRequest request) {
    String sessionId = CookieUtils.getCookieValue(request, SESSION_ID_COOKIE);
    redisClient.del(sessionId);
  }

  // 删除session在cookie中的sessionid
  private void clearSessionCookie(HttpServletRequest request, HttpServletResponse response) {
    Cookie sessionCookie = CookieUtils.getCookie(request, SESSION_ID_COOKIE);
    sessionCookie.setMaxAge(0);
    response.addCookie(sessionCookie);
  }
}

4、获取session

可以把获取session提取到公共的Controller中,这样需要使用session信息的类就可以继承这个类。

public class BaseController{

  @Autowired
  private RedisClient redisClient;

  protected Account getAccountFromSession(HttpServletRequest request) {
    String sessionCookieValue = CookieUtils.getCookieValue(request, "sessionid");
    if(StringUtils.isEmptyOrNull(sessionCookieValue)) {
      return null;
    } else {
      String accountJson = this.redisClient.get(sessionCookieValue);
      Account account = null;
      if(!StringUtils.isEmpty(accountJson)) {
        account = (Account)JSON.parseObject(casInfoJson, Account.class);
      }

      return account;
    }
  }

}

5、总结

使用第三方管理session时的基本步骤如下。

  • 进入登录页面保存sessionid到cookie中
  • 用户登录成功根据sessionid的值把Session保存在redis里面
  • 用户登出系统需要清除cookie中的sessionid,以及redis里面用户的session信息。

当用户登录成功之后进行其它操作就可以在request里面获取到用户的session信息。

 如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

更多精彩内容其他人还在看

Java Web实现的基本MVC实例分析

这篇文章主要介绍了Java Web实现的基本MVC,以完整实例形式较为详细的分析了JSP实现MVC架构的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

jsp中调用java代码小结

大多数情况下, jsp 文档的大部分由静态文本(html)构成, 为处理该页面而创建的 servlet 只是将它们原封不动的传递给客户端
收藏 0 赞 0 分享

jsp和servlet操作mysql中文乱码问题的解决办法

自己做测试的时候用到jsp/servlet 向mysql中写数据,但是中文总是乱码,今早纠结了半天才搞定,分享给大家我的解决办法
收藏 0 赞 0 分享

jsp跳转getRequestDispatcher()和sendRedirect()的区别

这篇文章主要介绍了jsp跳转getRequestDispatcher()和sendRedirect()的区别,需要的朋友可以参考下
收藏 0 赞 0 分享

java操作mysql入门代码实例(含插入、更新和查询)

这篇文章主要介绍了java操作mysql代码实例,通过执行SQL语句实现,需要的朋友可以参考下
收藏 0 赞 0 分享

struts2中一个表单中提交多个请求的例子(多个提交按钮)

在很多Web应用中,为了完成不同的工作,一个HTML form标签中可能有两个或多个submit按钮,Struts2中提供了另外一种方法,使得无需要配置可以在同一个action类中执行不同的方法(默认执行的是execute方法)
收藏 0 赞 0 分享

jsp中使用javabean实例介绍

这篇文章主要介绍了jsp中使用javabean的实例,同时介绍了相关属性,需要的朋友可以参考下
收藏 0 赞 0 分享

servlet中session简介和使用例子

在servlet中,session是封装在javax.servlet.http.HttpSession这个接口中的,这个接口是构建在cookie或者URL重写的基础上,要得到一个HttpSession的实例,就可以通过HttpServletRequest的getSession()
收藏 0 赞 0 分享

JSP中用回车监听按钮事件兼容火狐 IE等主流浏览器

这篇文章主要介绍了用回车监听按钮事件并且兼容火狐、IE等主流浏览器 ,需要的朋友可以参考下
收藏 0 赞 0 分享

JAVA velocity模板引擎使用实例

这篇文章主要介绍了JAVA velocity模板引擎使用实例,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多