2011-11-06 5 views
9

Estoy trabajando en una aplicación web en WinXP, Eclipse Indigo y Google web plugin.Servlet's sendRedirect() mata los atributos de mi sesión

Tengo un formulario simple que toma un valor del usuario (por ejemplo, correo electrónico), lo pasa a un servlet llamado SignIn.java que lo procesa y guarda el valor del correo electrónico en la sesión. SignIn El código es muy simple, esto es lo que hace la mayoría de su doGet:

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

Hasta aquí todo bien, He verificado que los valores no son null en este punto. Ahora viene el problema, quiero redirigir a otro servlet (ShowOnline.java) que necesita hacer un poco más de procesamiento. Cuando escribo

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

ShowOnline obtiene null valores de sesión (el mismo correo electrónico atributo ahorré un segundo antes es ahora null)

cuando escribo

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

todo está bien, el atributo de correo electrónico desde antes no es null!

¿Qué está pasando? sendRedirect() solo hace que su navegador envíe una nueva solicitud, no debería afectar el alcance de la sesión. He revisado las cookies y están bien (seguramente es la misma sesión de antes, ya que es la primera y única sesión que crea mi aplicación web y, además, incluso me molesté y verifiqué las ID de sesison y son las mismas en ambas solicitudes) .

¿Por qué habría una diferencia entre sendRedirect() y forward()? La solución más fácil sería usar forward(), pero quiero llegar al fondo de esto antes de dejarlo ir, creo que es importante para mí entender lo que sucedió. No estoy seguro de que me guste la idea de no saber lo que está pasando en conceptos tan básicos (toda mi aplicación web es muy simple y básica en este punto, ya que soy un principiante).

¡Cualquier idea o sugerencia sería bienvenida!

+0

supongo que podría ser posible en el momento de usar adelante en lugar de sendRedirect pero creo que más adelante me gustaría utilizar sendRedirect sin temor mis atributos de la sesión iría nula sin razón aparente. –

+0

@home: OP confirmó que la ID de sesión es la misma antes y después. – BalusC

+1

¿Qué sucede cuando no envía el redireccionamiento y va manualmente al/ShowOnlineServlet desde el navegador? –

Respuesta

1

Si su servlet SignIn solo está guardando un parámetro de solicitud (correo electrónico), entonces también puede reemplazar el servlet por un filter, p. SignInFilter.

SignInFilter contendría la misma lógica que su SignIn servlet (copiar el correo electrónico de los parámetros de la petición a la sesión), pero sería llamar al siguiente elemento de la cadena (que será su ShowOnline servlet) en lugar de hacer cualquier redirección/adelante.

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' 

} 

Configure su forma para publicar a la vez ShowOnline servlet, y configurar su nueva SignInFilter para ejecutar antes de ShowOnline (correlación de servlet se omite por razones de brevedad a continuación).

<?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

Por lo que yo sepa, sendRedirect() simplemente redirige el control a otra página sin transferir la solicitud & objeto de respuesta asociado de la página principal, pero RequestDispatcher (objeto) enviará a la ServletRequest y ServletResponse a la mencionada página en el argumento de ruta {getServletContext().getRequestDispatcher ("ruta")} después de eso, puede reenviar los objetos a esa página o incluir los objetos. Entonces, este contenedor se asegura de que tiene que usar el objeto de solicitud y respuesta anterior desde la página padre en lugar de crear uno nuevo. Especialmente si está utilizando la gestión de sesiones, la mejor opción es RequestDispatcher.

Espero que responda la pregunta.

Para todos: - Por favor, corríjanme si estoy equivocado.

@rs

Cuestiones relacionadas