En nuestros proyectos tenemos la necesidad que debido a ciertas circunstancias debemos redireccionar al usuario de nuestro sitio web a una página diferente, por ejemplo cuando un usuario no registrado ingresa a la página index.html debemos redireccionarlo a la página login.html.
Para entender mejor los mecanismos a utilizar revisemos brevemente y de una manera superficial el funcionamiento del protocolo HTTP. Un cliente hace una petición a un servidor web solicitando un recurso por ejemplo una página web esta petición es un mensaje que contiene un header y un body, en el header se envia información como la versión del protocolo la url del recurso solicitado, etc. El servidor web entiende este mensaje busca el recurso y retorna un mensaje de respuesta, este mensaje contiene igualmente un header y un body, en el body se encuentra el contenido del recurso solicitado para el ejemplo contiene el html de la página solicitada, y en el header contiene entre otras cosas un código de resultado de la petición, si todo fue exitoso este código es el 200, el browser entiende este código y muestra la página con el html recibido.
El servidor web también puede devolver códigos de error(>500) así como códigos indicando que el recurso fue movido temporalmente hacia otra URL, cuando esto pasa el mensaje de respuesta tiene como código de respuesta el número 302 y en el body la url del nuevo recurso, así pues el browser entiende el número 302 y navega (redirecciona - redirect) a la url recibida. A este mecanismo se lo conoce como un redirect en el cliente, ya que es el browser del cliente el que realiza el redireccionamiento. En el siguiente enlace pueden revisar la Lista de códigos del protocolo HTTP.
El hacer un redirect en en el cliente nos permite tener actualizada la url del browser, pero debemos realizar 2 peticiones hacia el servidor web. En JEE podemos implementar un redirect para el cliente utilizando el método sendRedirect de la clase HttpServletResponse. A continuación se muestra el código de ejemplo de como realizar un redirect.
@WebServlet(urlPatterns = { "/RedirectServlet" }, initParams = { @WebInitParam(name = "GoogleUrl", value = "http://www.google.com.ec") }) public class RedirectServlet extends HttpServlet { private static final long serialVersionUID = 7384755119447773498L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.getWriter().print("Escribiendo en el Html"); String redirectUrl = getServletConfig() .getInitParameter("GoogleUrl"); // Todo lo escrito anteriormente en el response //se pierde al hacer// redirect response.sendRedirect(redirectUrl); } }
También podemos realizar un redirect en el servidor es decir redireccionar la ejecución de un servlet o jsp hacia otro servlet o jsp, para ello debemos utilizar la clase RequestDispatcher. La ventaja principal es que el servlet o jsp al cual es redireccionado recibe el mismo request de la petición original, este mecanismo es muy utilizado para implementar un modelo MVC en el cual se solicita una url que es un servlet el servlet modifica el modelo e inserta valores en los atributos del request y hace un forward hacia un jsp que representa la vista. La principal ventaja del redirect en el servidor es que se realiza una sola petición la desventaja es que al realizarse la redirección en el servidor el cliente no es notificado y por lo tanto el browser permanece con la url original.
A continuación se muestra un ejemplo utilizando el RequestDispatcher.
@WebServlet("/DispatchServlet") public class DispatchServlet extends HttpServlet { private static final long serialVersionUID = -3130067528647522202L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType( getServletContext().getMimeType(".html")); response.getWriter().print("Escribiendo en el Html"); request.setAttribute("UserName", "César Loachamín"); //Al utilizar el dispatcher del request la url //debe ser relativa. Si se utiliza el dispatcher del //ServletContext la url debe ser absoluta RequestDispatcher dispatcher = request. getRequestDispatcher("Redirect.jsp"); //Se pierde todo el response anterior, si no se desea ese //comportamiento se puede usar la función include en lugar //de forward dispatcher.forward(request, response); } }
Cabe recalcar que al hacer un redirect se pierde todo el contenido del Response que hayamos modificado, además toca tener en cuenta de no hacer un flush al response antes de hacer un redirect pues ello lanazaría una excepción.
El proyecto en Maven con los ejemplos esta disponible para su descarga en el siguiente link.
Download: redirect-example.tar.gz
Para ejecutar, descomprimir el archivo. Dentro de la carpeta redirect-example ejecutar el siguiente comando mvn clean install tomcat7:run e ingresar a la url http://localhost:8080/redirect-example
También pueden deployar el war que genera en cualquier Application Server o contendor web como tomcat.
Hola, me gustaría saber como puedo hacer para que esto no ocurra:
ResponderEliminar"Cabe recalcar que al hacer un redirect se pierde todo el contenido del Response que hayamos modificado"
Que pueda volver, pero que estén todos los datos almacenados.
Estoy usando servlets y HTML
Tienes dos opciones: no hacer un redirect y utilizar el request RequestDispatcher.
EliminarLa otra opción es almacenar la información del primer request por ejemplo en sesión (u otro mecanismo de persistencia como bdd) y recuperarlos despues del redirect en la segunda pagina.
Tengo este fragmento de código
ResponderEliminarRequestDispatcher rd;
//rd = getServletContext().getRequestDispatcher(nextStop);
rd = request.getRequestDispatcher(nextStop);
if(nextStop.equals("formulario1.html"))
{
//response.setAttribute(nombre,nombre);
rd.forward(request,response);
}
else
{
rd.include(request,response);
}
Pero al volver al formulario no se encuentran guardados los valores
Hola que tal..mira.... es que tengo una duda con un proyecto jsp...
ResponderEliminarel codigo.... tengo un jsp que cuando se seleccione un pedido(numero) valla a otro jsp que procesa y retorna al primer jsp. Este retorno se hace con request.getRequestDispatcher("/ventas.jsp?totpedd="+totpedd+"&dia="+dia+"&bcli1=1").forward(request, response).
Cuando hago esto con un navegador en smartphone, efectivamente hace el retorno.., pero luego de terminar el jsp(ventas...) regresa al jsp que procesa y ahi termina...
lo que pasa es que se me han presentado registros repetidos en la database y no se si sea por este comportamiento... ademas viendo el http server monitor de netbeans, cuando llamo al jsp que procesa(esto lo envio por post con javascript), se hace el retorno a ventas(el primer jsp) via post pero luego veo GET /jquery-1.10.2.js... GET /js/jquery-ui-1.11.3/jquery-ui.js... entre otros...
utilizo librerias de jquery y las tengo dentro del head del primer jsp...
No entiendo si este comportamiento esta bien o mal... agradezco colaboracion...