Spring mvc 分步式session的實(shí)例詳解
Session代表服務(wù)器與瀏覽器的一次會(huì)話過程,它的信息是保存在服務(wù)器端的。在Servlet中,session指的是HttpSession類的對(duì)象。服務(wù)器在創(chuàng)建session后,會(huì)把sessionid以cookie的形式回寫給客戶端。只要客戶端的瀏覽器不關(guān),每一次訪問服務(wù)器都會(huì)帶上這個(gè)sessionid。這樣就可以在每次請(qǐng)求的時(shí)候獲取到session的信息。
下面以spring MVC以例來說明如果創(chuàng)建分步式session.
1、login – 登錄頁
login表示用戶跳轉(zhuǎn)到登錄頁面,這個(gè)時(shí)候可以生成唯一key為sessionid的sesssionid。保存sessionid到response中,當(dāng)用戶真正登錄的時(shí)候獲取sessionid,因?yàn)槭欠植绞剿越y(tǒng)一的管理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);
}
// 其它業(yè)務(wù)相關(guān)信息
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 – 身份認(rèn)證/登錄
用戶輸入用戶名密碼,需要在后臺(tái)進(jìn)行登錄。此時(shí)可以從cookie中獲取到sessionid,然后再?gòu)膔edis里面獲取到它的值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){
ResponseInfoObject> responseInfo = new ResponseInfoObject>();
try {
Account account = authenticate(username, password);
saveSession(account);
responseInfo.setStatus(0);
responseInfo.setMessage("success");
} catch(Exceptioin e){
responseInfo.setStatus(1);
responseInfo.setMessage("服務(wù)器正忙,請(qǐng)稍候重試")
}
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 – 登出
當(dāng)用戶選擇退出系統(tǒng)時(shí),需要把頁面跳轉(zhuǎn)到登錄頁面也就是第一步并且需要?jiǎng)h除在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信息的類就可以繼承這個(gè)類。
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、總結(jié)
使用第三方管理session時(shí)的基本步驟如下。
- 進(jìn)入登錄頁面保存sessionid到cookie中
- 用戶登錄成功根據(jù)sessionid的值把Session保存在redis里面
- 用戶登出系統(tǒng)需要清除cookie中的sessionid,以及redis里面用戶的session信息。
當(dāng)用戶登錄成功之后進(jìn)行其它操作就可以在request里面獲取到用戶的session信息。
如有疑問請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
您可能感興趣的文章:- 詳解Spring mvc ant path的使用方法
- Spring MVC全局異常處理和單元測(cè)試_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Spring MVC入門_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Spring MVC之DispatcherServlet_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Spring MVC之WebApplicationContext_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Spring MVC訪問靜態(tài)文件_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- spring mvc常用注解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- springMVC圖片上傳的處理方式詳解