Spring mvc 分步式session的實(shí)例詳解
Spring mvc 分步式session的實(shí)例詳解
Session代表服務(wù)器與瀏覽器的一次會(huì)話過(guò)程,它的信息是保存在服務(wù)器端的。在Servlet中,session指的是HttpSession類(lèi)的對(duì)象。服務(wù)器在創(chuàng)建session后,會(huì)把sessionid以cookie的形式回寫(xiě)給客戶端。只要客戶端的瀏覽器不關(guān),每一次訪問(wèn)服務(wù)器都會(huì)帶上這個(gè)sessionid。這樣就可以在每次請(qǐng)求的時(shí)候獲取到session的信息。
下面以spring MVC以例來(lái)說(shuō)明如果創(chuàng)建分步式session.
1、login – 登錄頁(yè)
login表示用戶跳轉(zhuǎn)到登錄頁(yè)面,這個(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){
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("服務(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í),需要把頁(yè)面跳轉(zhuǎn)到登錄頁(yè)面也就是第一步并且需要?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) {
// 獲取到重定向位置也就是登錄頁(yè)
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信息的類(lèi)就可以繼承這個(gè)類(lèi)。
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)入登錄頁(yè)面保存sessionid到cookie中
- 用戶登錄成功根據(jù)sessionid的值把Session保存在redis里面
- 用戶登出系統(tǒng)需要清除cookie中的sessionid,以及redis里面用戶的session信息。
當(dāng)用戶登錄成功之后進(jìn)行其它操作就可以在request里面獲取到用戶的session信息。
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- 詳解Spring mvc ant path的使用方法
- Spring MVC全局異常處理和單元測(cè)試_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Spring MVC入門(mén)_動(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訪問(wèn)靜態(tài)文件_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- spring mvc常用注解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- springMVC圖片上傳的處理方式詳解
相關(guān)文章
Hibernate實(shí)體對(duì)象繼承的三種方法
這篇文章主要介紹了Hibernate實(shí)體對(duì)象繼承的方法的相關(guān)資料,需要的朋友可以參考下2017-06-06
jsp頁(yè)面中EL表達(dá)式被當(dāng)成字符串處理不顯示值問(wèn)題的解決方法
下面小編就為大家?guī)?lái)一篇jsp頁(yè)面中EL表達(dá)式被當(dāng)成字符串處理不顯示值問(wèn)題的解決方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
用JS實(shí)現(xiàn)購(gòu)物網(wǎng)站商品放大鏡效果
大家?guī)缀醵加性诰W(wǎng)上購(gòu)物的經(jīng)驗(yàn),有的網(wǎng)站會(huì)有一個(gè)商品放大鏡功能,這篇文章主要介紹了用JS實(shí)現(xiàn)購(gòu)物網(wǎng)站商品放大鏡效果,有需要的朋友可以看看。2016-10-10
EJB3.0開(kāi)發(fā)之多對(duì)多和一對(duì)一
EJB3.0開(kāi)發(fā)之多對(duì)多和一對(duì)一...2006-10-10
JSP內(nèi)置對(duì)象:Request和Response的簡(jiǎn)單介紹及使用
JSP內(nèi)置對(duì)象:Request和Response的簡(jiǎn)單介紹及使用,需要的朋友可以參考一下2013-02-02
Jsp和PHP共用80端口整合Apache和Tomcat(訪問(wèn)時(shí)無(wú)需加端口號(hào))
整合Apache和Tomcat,使得Java工程和PHP工程都能共用80端口,訪問(wèn)網(wǎng)站時(shí),無(wú)需在地址欄中加端口號(hào),具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈2013-06-06

