2013-07-23 51 views
0

我對JSF 2.0中的會話管理方式感到困惑。JSF 2.0中的會話管理

我創建了4頁登錄,數據,信息和sessionexpires,顯示會話已過期。

當我點擊退出按鈕,它通過調用下面的操作方法失效會話:

public String logout(){ 
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); 
    return "logout?faces-redirect=true"; 
} 

代碼重定向我註銷頁,符合市場預期,但是當我點擊瀏覽器的後退按鈕,它需要我數據頁面並顯示所有信息,但我認爲,如果會話已過期,則應顯示sessionexpires頁面。

如何實現所需的功能?

+0

[避免JSF Web應用程序上的後退按鈕](http:// stackoverflow。com/questions/10305718/avoid-back-button-on-jsf-web-application) – BalusC

+0

非常感謝@BalusC,但我的問題仍然不是在單擊後退按鈕上完全緩存頁面,而是在緩存頁面上,爲什麼在點擊時執行操作的命令按鈕,如果我無效的會話 –

回答

3

當用戶單擊瀏覽器的後退按鈕時,您會看到上一頁,這表明頁面已緩存,並且從瀏覽器的緩存中顯示,而不是從服務器請求的頁面。要修復它,你需要適當地設置HTTP響應頭。這已在Making sure a web page is not cached, across all browsers中事先得到解答。只是重複BalusC,它們是:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. 
response.setHeader("Pragma", "no-cache"); // HTTP 1.0. 
response.setDateHeader("Expires", 0); // Proxies. 

最合適的地方設置這些標題是網頁過濾器,你似乎並不需要任何JSF財物那裏。您可以在Avoid back button on JSF web application的答案中找到更多信息。要重複BalusC的代碼,您將擁有:

@WebFilter("/secured/*") 
public class NoCacheFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 

     if (!request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc) 
      response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. 
      response.setHeader("Pragma", "no-cache"); // HTTP 1.0. 
      response.setDateHeader("Expires", 0); // Proxies. 
     } 

     chain.doFilter(req, res); 
    } 

    // ... 

} 

只要不要忘記告訴您需要過濾哪些頁面。這樣,所請求的新頁面將始終從服務器發送,而不會再被緩存。因此,如果用戶在註銷發生後嘗試訪問受保護的頁面(通過會話失效併發送重定向),則您的標準安全手段將會啓動(其他過濾器),從而阻止用戶訪問這些頁面。

接下來要做的事情是解釋JSF如何在會話失效/超時時處理已打開的頁面。換句話說,你如何處理ViewExpiredException s。對於同步POST請求,這又在How to handle session expiration and ViewExpiredException in JSF 2?javax.faces.application.ViewExpiredException: View could not be restored中進行了回答,對於AJAX請求在Session timeout and ViewExpiredException handling on JSF/PrimeFaces ajax request中進行了回答。

基本上,對於前者,你需要以下幾行添加到你的web.xml:

<error-page> 
    <exception-type>javax.faces.application.ViewExpiredException</exception-type> 
    <location>/expired.xhtml</location> 
</error-page> 

對於後者,我熱烈推薦你看看JSF工具庫OmniFaces及其FullAjaxExceptionHAndler這是爲此設計。

+0

非常感謝@skuntsel,但我仍然試圖做的是,當用戶點擊該緩存頁面命令按鈕時,它應該將sessionsexpires頁面(因爲我無效的會話),但不會執行單擊該按鈕時的操作 –

0

即使服務器上的會話失效,瀏覽器也會將您帶回數據頁面,因爲該頁面緩存在瀏覽器內存中。

按照this關於瀏覽器的後退按鈕如何工作。

您可以參考this來解決您的問題。

+0

謝謝@joe,但這不是我的問題,我知道頁面緩存,因爲我從[這裏]瞭解到(http://stackoverflow.com/questions/5619827/how-to- invalidate-session-in-jsf-2-0)由BalusC,但如果我點擊任何命令按鈕,它應該帶我到sessionexpire頁面,但不是通過該按鈕請求頁面的頁面。 –