轉: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); }