2011-11-06 40 views
9

我正在使用WinXP,Eclipse Indigo和Google web插件的webapp。Servlet的sendRedirect()殺死我的會話屬性

我有一個簡單的表單,它從用戶(例如電子郵件)獲取一個值,並將其傳遞給一個名爲SignIn.java的servlet,該servlet處理它並將電子郵件值保存到會話中。 的SignIn代碼很簡單,這裏是它的主要doGet做:

String email = req.getParameter("email"); //getting the parameter from html form 
... 
... 
HttpSession session = req.getSession();  //create a new session 
session.setAttribute("email", email); 

到目前爲止好,我已經驗證該值不null在這一點上。現在出現這個問題,我想重定向到另一個需要做更多處理的servlet(ShowOnline.java)。當我寫

resp.sendRedirect(resp.encodeRedirectURL("/ShowOnlineServlet")); 

ShowOnline得到null會話值(相同的電子郵件屬性我保存了第二個是現在擺在null

當我寫

getServletConfig().getServletContext().getRequestDispatcher("/ShowOnlineServlet"); 

一切都OK,電子郵件屬性從前不是null

這是怎麼回事? sendRedirect()只是讓你的瀏覽器發送一個新的請求,它不應該影響會話範圍。我檢查了這些cookie,它們都沒問題(它確實是和以前相同的會話,因爲它是我的Web應用程序創建的第一個也是唯一的會話,此外我甚至打擾並檢查了sesison ID,它們在兩個請求中都是相同的) 。

爲什麼sendRedirect()forward()之間有區別?簡單的解決方案是使用forward(),但我想在放下之前先深入到底,我認爲了解發生的事情對我來說很重要。我不確定我喜歡不知道這些基本概念上發生了什麼的想法(因爲我是初學者,所以我的整個webapp非常簡單和基本)。

任何想法的想法或建議將受到熱烈歡迎!

+0

我猜有可能在一瞬間向前,而不是使用的sendRedirect但我想以後我會想不用擔心我的會話屬性會去空無緣無故的sendRedirect使用。 –

+0

@home:OP確認前後的會話ID相同。 – BalusC

+1

當您不發送重定向並從瀏覽器手動轉到/ ShowOnlineServlet時會發生什麼? –

回答

1

如果您的SignIn servlet只保存一個請求參數(email),那麼您也可以用一個filter(例如, SignInFilter

SignInFilter將包含相同的邏輯,你SignIn的servlet(複製從請求參數到會話中的電子郵件),但會叫,而不是做任何重定向鏈中的下一個項目(這將是你的ShowOnline的servlet)/前鋒。

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
    throws IOException, ServletException { 

    HttpServletRequest request = (HttpServletRequest) req; 
    HttpServletResponse response = (HttpServletResponse) res; 
    HttpSession session = request.getSession(); 

    String email = req.getParameter("email"); 
    session.setAttribute("email", email); 

    chain.doFilter(req, res); // continue to 'ShowOnline' 

} 

設置您的形式張貼到ShowOnline的servlet,而是和配置新SignInFilter之前ShowOnline(爲了簡潔下面省略servlet映射)來執行。

<?xml version="1.0" encoding="UTF-8"?> 
<web-app 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    id="WebApp_ID" version="2.5"> 

    <filter> 
     <filter-name>SignInFilter</filter-name> 
     <filter-class>com.example.SignInFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>SignInFilter</filter-name> 
     <url-pattern>/ShowOnline</url-pattern> 
    </filter-mapping> 
</web-app> 
-2

據我所知,的sendRedirect()控制只是重定向到另一個頁面,而不transfering父頁面的相關請求&響應對象,但RequestDispatcher的(對象)將調度的ServletRequest和ServletResponse的所提到的頁面在路徑參數{getServletContext()中。getRequestDispatcher(「path」)}之後,您可以將對象轉發到該頁面或包含對象。所以通過這個容器可以確保他必須使用父頁面的前一個請求和響應對象,而不是創建新的。 特別是如果您使用會話管理,最好的選擇是RequestDispatcher。

希望能回答這個問題。

To All: - 請糾正我,如果我錯了。

@rs