简体   繁体   English

Servlet的sendRedirect()会终止我的会话属性

[英]Servlet's sendRedirect() kills my session attributes

I am working on a webapp in WinXP, Eclipse Indigo and Google web plugin. 我正在使用WinXP,Eclipse Indigo和Google web插件中的webapp。

I have a simple form that takes a value from user (eg email) , passes it to a servlet named SignIn.java that processes it and saves the email value to the session. 我有一个从用户获取值的简单表单(例如电子邮件),将其传递给名为SignIn.java的servlet,该servlet处理它并将电子邮件值保存到会话中。 The SignIn code is very simple , here is what its doGet mostly does: 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);

So far so good, I've verified that the values aren't null at this point. 到目前为止,我已经验证了此时值不为null Now comes the problem, I want to redirect to another servlet ( ShowOnline.java ) that needs to do some more processing. 现在出现了问题,我想重定向到需要进行更多处理的另一个servlet( ShowOnline.java )。 When I write 当我写作

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

ShowOnline gets null session values (the same email attribute I saved a second before is now null ) ShowOnline获取null会话值(我之前保存的相同电子邮件属性现在为null

When I write 当我写作

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

everything is OK, the email attribute from before isn't null ! 一切都还可以,之前的email属性不是null

What is going on? 到底是怎么回事? sendRedirect() just makes your browser send a new request, it shouldn't affect the session scope. sendRedirect()只是让你的浏览器发送一个新请求,它不应该影响会话范围。 I have checked the cookies and they are fine (it is the same session from before for sure since it is the first and only session my webapp creates and furthermore I even bothered and checked the sesison ID's and they're the same on both requests). 我已经检查了cookie并且它们很好(这是以前的会话,因为它是我的webapp创建的第一个也是唯一一个会话,而且我甚至打扰并检查了sesison ID,并且它们在两个请求中都是相同的) 。

Why would there be a difference between sendRedirect() and forward() ? 为什么sendRedirect()forward()之间会有区别? The easy solution would be to use forward() but I want to get to the bottom of this before I just let go , I think it is important for me to understand what happened. 简单的解决方案是使用forward()但我想在我放手之前找到底部,我认为理解发生的事情对我来说很重要。 I'm not sure I like the idea of not knowing what's going on on such basic concepts (my whole webapp is very simple and basic at this point since I'm a beginner). 我不确定我喜欢不知道这些基本概念发生了什么的想法(因为我是初学者,我的整个webapp在这一点上非常简单和基本)。

Any thoughts ideas or suggestions would be warmly welcome ! 任何想法的想法或建议都将受到热烈欢迎!

If your SignIn servlet is only saving a request parameter (email), then you could also replace the servlet with a filter , eg SignInFilter . 如果您的SignIn servlet仅保存请求参数(email),那么您还可以使用过滤器替换servlet,例如SignInFilter

SignInFilter would contain the same logic as your SignIn servlet (copying the email from the request parameters to the session), but would call the next item in the chain (which will be your ShowOnline servlet) instead of doing any redirect/forward. 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'

}

Set up your form to POST to the ShowOnline servlet instead, and configure your new SignInFilter to execute before ShowOnline (servlet mapping omitted below for brevity). 将表单设置为POST到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>

As far as my knowledge, sendRedirect() just redirects the control to another page without transfering the associated request & response object of parent page, but RequestDispatcher(object) will dispatch the ServletRequest and ServletResponse to the page mentioned in path argument { getServletContext().getRequestDispatcher("path")} after that you can either forward the objects to that page or include the objects. 据我所知,sendRedirect()只是将控件重定向到另一个页面而不传输父页面的关联请求和响应对象,但RequestDispatcher(object)会将ServletRequest和ServletResponse调度到路径参数{getServletContext()中提到的页面。 .getRequestDispatcher(“path”)}之后,您可以将对象转发到该页面或包含对象。 So by this container becomes assured that he has to use the previous request and response object from of the parent page instead of creating new one. 因此,通过此容器可以确保他必须使用父页面中的先前请求和响应对象,而不是创建新的请求和响应对象。 Specially if you are using session management the best option is RequestDispatcher. 特别是如果您使用会话管理,最好的选择是RequestDispatcher。

Hope that answers the question. 希望能回答这个问题。

To All :- Please correct me if i am wrong. 致全部: - 如果我错了,请纠正我。

@rs @rs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM