2011-11-06 48 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