轉:http://blog.csdn.net/lhacker/article/details/20450855
很多時候,我們需要做到,當用戶登錄成功后,跳轉回登錄前的頁面。如果用戶是點擊"登錄"鏈接去到登錄頁面進行登錄的,我們很容易跟蹤用戶的登錄前的頁面。比如,在"登錄"鏈接后加一個url參數,如:http://www.xxx.com/login.html?url=http://www.xxx.com/xx.html,這個url就是當前頁面。用戶瀏覽不同頁面,"登錄"鏈接后面的url跟着改變。這樣,跳轉到登錄頁面時都會帶有上一個頁面的url作為參數,登錄后也很容易拿到這個參數進行重定向到登錄前的頁面。
但當我們用配置/xxx.html=authc這種方式,限制用戶訪問/xxx.html連接時必須是認證過的用戶,否則shiro的filter將會重定向到登錄頁面,上面的方法應當好處理了。不過shiro在跳轉前有記錄跳轉前的頁面。前沒有認證的用戶請求需要認證的鏈接時,shiro在跳轉前會把跳轉過來的頁面鏈接保存到session的attribute中,key的值叫shiroSavedRequest,我們可以能過WebUtils類拿到。
當用戶登錄成功后,可能通過String url = WebUtils.getSavedRequest(request).getRequestUrl();,拿到跳轉到登錄頁面前的url,然后redirect到這個url。其實我們可以看看這個方法的源碼:
public static SavedRequest getSavedRequest(ServletRequest request) {
SavedRequest savedRequest = null;
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession(false);
if (session != null) {
savedRequest = (SavedRequest) session.getAttribute(SAVED_REQUEST_KEY);
}
return savedRequest;
}
從session中拿到SaveRequest。不過值得注意的是,這個SaveRequest是在用戶通過上面方式跳轉登錄時shiro才會保存,並且不會改變,除非下一次跳轉再次發生。並不是每一個請求,shiro都會把上一個請求保存到session中。所以,不能通過WebUtils.getSavedRequest(request)在任何地方調用來拿到上一個頁面的請求。這個方法的調用,更應該是在用戶登錄成功后,重定向到頁面時使用。
下面是我在項目中的實現:
使用shiro登錄成功后,會調用FormAuthenticationFilter的issueSuccessRedirect方法,在項目實現的時候重寫了該方法,實現如下:
@Override
protected void issueSuccessRedirect(ServletRequest request,
ServletResponse response) throws Exception {
SavedRequest savedRequest = WebUtils.getSavedRequest(request);
String superURL = null;
if(savedRequest!=null){
superURL = savedRequest.getRequestUrl();
if(superURL==null||"".equals(superURL)){
superURL = getSuccessUrl();
}else if(superURL.contains("/CBSP")){
superURL = superURL.replace("/CBSP", "");
}
}else{
superURL = getSuccessUrl();
}
WebUtils.issueRedirect(request, response, superURL, null, true);
}
