2010-01-07 101 views
1

我是一個新手servlet程序員。我正在努力做到這一點。設計問題 - 重定向URL

我寫了一個過濾器攔截Servlet請求,並檢查URL需要先登錄用戶。如果是這樣的用戶被定向到登錄頁面。這是行得通的。但是,我想將用戶重定向到他想要去的頁面。保持這種狀態的正確方法是什麼?我只是將URL存儲在使用Cookie中的會話ID索引的數據結構中?

回答

1

我寫了一個過濾器攔截servlet請求,並檢查URL需要在要記錄用戶

這似乎聽起來不錯。你還是在Servlet相同url-pattern映射Filter,或更好,但在Servletservlet-name。這樣Filter只有調用Servlet時才調用

返回到您的實際問題:在不登錄的用戶,你有兩個選擇:

  1. 存儲在會話的網址:

    if (session.getAttribute("user") == null) { 
        session.setAttribute("back", httpRequest.getRequestURI()); 
        httpRequest.sendRedirect("login"); 
    } else { 
        chain.doFilter(request, response); 
    } 
    

    您在登錄時使用:

    User user = userDAO.find(username, password); 
    if (user != null) { 
        session.setAttribute("user", user); 
        String back = (String) session.getAttribute("back"); 
        if (back != null) { 
         session.removeAttribute("back"); 
         response.sendRedirect(back); 
        } else { 
         response.sendRedirect("home"); // Home page? 
        } 
    } else { 
        // Show error? 
        request.setAttribute("message", "Unknown user, please retry"); 
        request.getRequestDispatcher("login").forward(request, response); 
    } 
    
  2. 傳遞URL作爲請求參數:

    if (session.getAttribute("user") == null) { 
        httpRequest.sendRedirect("login?back=" + httpRequest.getRequestURI()); 
    } else { 
        chain.doFilter(request, response); 
    } 
    
    您通過爲隱藏輸入字段後續請求

    <input type="hidden" name="back" value="${param.back}"> 
    

    您在登錄時使用:

    User user = userDAO.find(username, password); 
    if (user != null) { 
        session.setAttribute("user", user); 
        String back = request.getParameter("back"); 
        if (back != null) { 
         response.sendRedirect(back); 
        } else { 
         response.sendRedirect("home"); // Home page? 
        } 
    } else { 
        // Show error? 
        request.setAttribute("message", "Unknown user, please retry"); 
        request.getRequestDispatcher("login").forward(request, response); 
    } 
    

URL編碼的一些建議是沒有必要的getRequestURI()將不會被解碼。

+0

非常感謝您的詳細回覆。您的回覆爲我提供了2分,但我沒有解決 - 您說過 - 您應該將過濾器映射到Servlet的相同url模式,或者更好的方式是將Servlet的名稱與Servlet名稱相關聯 這是標準做法嗎?我正在爲每個功能編寫一個過濾器。例如一個用於日誌記錄,一個用於驗證檢查。我將這些映射到所有jsps和servlet。 我會在另一條評論中寫下第二個問題。 – user220201 2010-01-08 03:13:43

+0

您從字面上說您正在檢查過濾器中的URL以查看用戶是否需要登錄。如果您將過濾器映射到覆蓋該URL的'url-pattern',則這是不必要的。或者,如果在同一個'url-pattern'上已經有一些控制器servlet,那麼將它映射到該servlet上。無論哪種方式,過濾器都不會被不必要地調用。 – BalusC 2010-01-08 03:20:42

+0

另一個問題是關於使用數據庫的認證。到目前爲止,我編寫了自己的數據庫連接類,並自己編寫了所有代碼或數據庫操作。我知道我可以使用Hibernate。但是有沒有特定的認證本身?什麼是userDAO。另外,Asaph正在討論tomcat內置的安全支持。大規模應用的首選方式是什麼(面向消費者而不是企業)? - 謝謝。 – user220201 2010-01-08 03:44:22

2

您可以將其存儲在一個會話也可以將其添加到登錄的網址。

http://www.myexample.com/login.jsp?from=mypage.jsp 

確保您url encode它(用適當的轉義值替換/,&,=,等等(%XX)),如果它有一個路徑和文件名。

http://www.myexample.com/login.jsp?from=mydir%2Fmypage.jsp 
+0

謝謝!我知道這樣做會有更好的方式。我是C程序員,所以嘗試創建一切的數據結構:) – user220201 2010-01-08 03:08:59

1

不要重新發明輪子。 Servlet API支持基於用戶/角色的身份驗證和安全性。 Tomcat的(除了別的以外)包括:built in support for authenticating使用各種來源:xml文件,數據庫,LDAP等

+0

世界需要多少個驗證輪? – Timothy 2010-01-08 14:27:36