Servlets y JSP

Cuando un servidor Web responde a una petici�n de un navegador u otro cliente Web, la respuesta consiste t�picamente en una l�nea de estado, algunas cabeceras de respuesta, una l�nea en blanco, y el documento. Aqu� tenemos un ejemplo m�nimo:

 HTTP/1.1 200 OK
Content-Type: text/plain

Hello World

La l�nea de estado consiste en la versi�n HTTP, y un entero que se interpreta como c�digo de estado, y un mensaje muy corto que corresponde con el c�digo de estado. En la mayor�a de los casos, todas las cabeceras son opcionales excepto Content-Type, que especifica el tipo MIME del documento que sigue. Aunque muchas respuestas contienen un documento, algunas no lo tienen. Por ejemplo, las respuestas a peticiones HEAD nunca deber�an incluir un documento, y hay una gran variedad de c�digos de estado que esencialmente indican fallos, y o no incluyen un documento o s�lo incluyen un peque�o "mensaje de error de documento".

Los servlets pueden realizar una variedad de tareas manipulando la l�nea de estado y las cabeceras de respuesta. Por ejemplo, reenviar al usuario a otros sites; indicar que el documento adjunto es una imagen, un fichero Acrobat, o (m�s comunmente) un fichero HTML; decirle al usuario que se requiere una password para acceder al documento; etc. Esta secci�n explica varios c�digos de estados diferentes y como se pueden conseguir, mientras que la p�gina siguiente describe la cabeceras de respuesta.

.�Especificar C�digos de Estado

Como se describe arriba, la l�nea de estado de respuesta HTPP consiste en una versi�n HTTP, un c�digo de estado, y un mensaje asociado. Como el mensaje est� asociado directamente con el c�digo de estado y la versi�n HTTP est� determinada por el servidor, todo lo que servidor tiene que hacer es seleccionar el c�digo de estado. La forma de hacer esto es mediante el m�todo setStatus de HttpServletResponse. El m�todo setStatus toma un int (el c�digo de estado) como argumento, pero en vez de usar los n�mero expl�citamente, es m�s claro y legible usar las constantes definidas en HttpServletResponse. El nombre de cada constante est� derivado del mensaje est�ndard HTTP 1.1 para cada constante, todo en may�sculas con un prefijo SC (por Status Code) y los espacios se cambian por subrayados. As�, como el mensaje para 404 es Not Found, la constante equivalente en HttpServletResponse es SC_NOT_FOUND. Sin embargo, hay dos excepciones. Por alguna raz�n oculta la constante para el c�digo 302 se deriva del mensaje HTTP 1.0, no de HTTP 1.1, y la constante para el c�digo 307 no existe tampoco.

Seleccionar el c�digo de estado no siempre signifia que no necesitemos devolver un documento. Por ejemplo, aunque la mayor�a de los servidores generar�n un peque�o mensaje "File Not Found" para respuestas 404, un servlet podr�a querer personalizar esta respuesta. Sin embargo, si hacemos esto, necesitamos estar seguros de llamar a response.setStatus antes de enviar el contenido mediante PrintWriter.

Aunque el m�todo general de selecci�n del c�digo de estado es simplemente llamar a response.setStatus(int), hay dos casos comunes para los que se proporciona un m�todo atajo en HttpServletResponse. El m�todo sendError genera un respuesta 404 junto con un mensaje corto formateado dentro de un documento HTML. Y el m�todo sendRedirect genera una respuesta 302 junto con una cabecera Location indicando la URL del nuevo documento.

.�C�digos de Estado HTTP 1.1 y sus Significados

Aqu� hay una lista de todas los c�digos de estado disponibles en HTTP 1.1 junto con sus mensajes asociados y su interpretaci�n. Deber�amos ser cuidadosos al utilizar los c�digos de estado que est�n disponibles s�lo en HTTP 1.1, ya que muchos navegadores s�lo soportan HTTP 1.0. Si tenemos que usar c�digos de estado espec�ficos para HTTP 1.1, en la mayor�a de los casos querremos chequear expl�citamente la versi�n HTTP de la petici�n (mediante el m�todo getProtocol de HttpServletRequest) o reservarlo para situaciones donde no importe el significado de la cabecera HTTP 1.0.

C�digo de Estado Mensaje Asociado Significado
100 Continue Contin�a con petici�n parcial (nuevo en HTTP 1.1)
101 Switching Protocols El servidor cumplir� con la cabecera Upgrade y cambiar� a un protocolo diferente. (Nuevo en HTTP 1.1)
200 OK Todo est� bien; los documentos seguidos por peticiones GET y POST. Esto es por defecto para los Servlets, si no usamos setStatus, obtendremos esto.
201 Created El servidor creo un documento; la cabecera Location indica la URL.
202 Accepted La petici�n se est� realizando, el proceso no se ha completado.
203 Non-Authoritative Information El documento est� siendo devuelto normalmente, pero algunas cabeceras de respuesta podr�an ser incorrectas porque se est� usando una copia del documento (Nuevo en HTTP 1.1)
204 No Content No hay un documento nuevo; el navegador cont�nua mostrando el documento anterior. Esto es �til si el usuario recarga peri�dicamente una p�gina y podemos determinar que la p�gina anterior ya est� actualizada. Sin embargo, esto no funciona para p�ginas que se recargan autom�ticamente mediante cabeceras de respuesta Refresh o su equivalente <META HTTP-EQUIV="Refresh" ...>,ya que al devolver este c�digo de estado se parar�n futuras recargas.
205 Reset Content No hay documento nuevo, pero el navegador deber�a resetear el documento. Usado para forzar al navegador a borrar los contenidos de los campos de un formulario CGI (Nuevo en HTTP 1.1)
206 Partial Content El cliente env�a una petici�n parcial con una cabecera Range, y el servidor la ha completado. (Nuevo en HTTP 1.1)
300 Multiple Choices El documento pedido se puede encontrar en varios sitios; ser�n listados en el documento devuelto. Si el servidor tiene una opci�n preferida, deber�a listarse en la cabecera de respuesta Location .
301 Moved Permanently El documento pedido est� en alg�n lugar, y la URL se da en la cabecera de respuesta Location. Los navegadores deber�an seguir autom�ticamente el enlace a la nueva URL.
302 Found Similar a 301, excepto que la nueva URL deber�a ser interpretada como reemplazada temporalmente, no permanentemente. Observa: el mensaje era "Moved Temporarily" en HTTP 1.0, y la constante en HttpServletResponse es SC_MOVED_TEMPORARILY, no SC_FOUND. Cabecera muy �til, ya que los navegadores siguen autom�ticamente el enlace a la nueva URL. Este c�digo de estado es tan �til que hay un m�todo especial para ella, sendRedirect. Usar response.sendRedirect(url) tiene un par de ventajas sobre hacer response.setStatus(response.SC_MOVED_TEMPORARILY) y response.setHeader("Location", url). Primero, es m�s f�cil. Segundo, con sendRedirect, el servlet autom�ticamente construye una p�gina que contiene el enlace (para mostrar a los viejos navegadores que no siguen las redirecciones autom�ticamente). Finalmente, sendRedirect puede manejar URLs relativas, autom�ticamentes las traducen a absolutas.

Observa que este c�digo de estado es usado algunas veces de forma intercambiada con 301. Por ejemplo, si err�neamente pedimos http://host/~user (olvidando la �ltima barra), algunos servidores enviar�n 301 y otros 302.

T�cnicamente, se supone que los navegadores siguen autom�ticamente la redirecci�n su la petici�n original era GET. Puedes ver la cabecera 307 para m�s detalles.

303 See Other Igual que 301/302, excepto que si la petici�n original era POST, el documento redirigido (dado en la cabecera Location) deber�a ser recuperado mediante GET. (Nuevo en HTTP 1.1)
304 Not Modified El cliente tiene un documento en el cach� y realiza una petici�n condicional (normalmente suministrando una cabecera If-Modified-Since indicando que s�lo quiere documentos m�s nuevos que la fecha especificada). El servidor quiere decirle al cliente que el viejo documento del cach� todav�a est� en uso.
305 Use Proxy El documento pedido deber�a recuperarse mediante el proxy listado en la cabecera Location. (Nuevo en HTTP 1.1)
307 Temporary Redirect Es id�ntica a 302 ("Found" o "Temporarily Moved"). Fue a��dido a HTTP 1.1 ya que muchos navegadores siguen err�neamente la redirecci�n de una respuesta 302 incluso si el mensaje original fue un POST, y s�lo se debe seguir la redirecci�n de una petici�n POST en respuestas 303. Esta respuesta es algo amb�gua: sigue el redireccionamiento para peticiones GET y POST en el caso de respuestas 303, y en el caso de respuesta 307 s�lo sigue la redirecci�n de peticiones GET. Nota: por alguna raz�n no existe una constante en HttpServletResponse que corresponda con este c�digo de estado. (Nuevo en HTTP 1.1)
400 Bad Request Mala S�ntaxis de la petici�n.
401 Unauthorized El cliente intenta acceder a una p�gina protegida por password sin las autorizaci�n apropiada. La respuesta deber�a incluir una cabecera WWW-Authenticate que el navegador deber�a usar para mostrar la caja de di�logo usuario/password, que viene de vuelta con la cabecera Authorization.
403 Forbidden El recurso no est� disponible, si importar la autorizaci�n. Normalmente indica la falta permisos de fichero o directorios en el servidor.
404 Not Found No se pudo encontrar el recurso en esa direcci�n. Esta la respuesta est�ndard "no such page". Es tan c�m�n y �til esta respuesta que hay un m�todo especial para ella en HttpServletResponse: sendError(message). La ventaja de sendError sobre setStatus es que, con sendErr, el servidor genera autom�ticamente una p�gina que muestra un mensaje de error.
405 Method Not Allowed El m�todo de la petici�n (GET, POST, HEAD, DELETE, PUT, TRACE, etc.) no estaba permitido para este recurso particular. (Nuevo en HTTP 1.1)
406 Not Acceptable El recurso indicado genera un tipo MIME incompatible con el especificado por el cliente mediante su cabecera Accept. (Nuevo en HTTP 1.1)
407 Proxy Authentication Required Similar a 401, pero el servidor proxy deber�a devolver una cabecera Proxy-Authenticate. (Nuevo en HTTP 1.1)
408 Request Timeout El cliente tarda demasiado en env�ar la petici�n. (Nuevo en HTTP 1.1)
409 Conflict Usualmente asociado con peticiones PUT; usado para situaciones como la carga de una versi�n incorrecta de un fichero. (Nuevo en HTTP 1.1)
410 Gone El documento se ha ido; no se conoce la direcci�n de reenvio. Difiere de la 404 en que se sabe que el documento se ha ido permanentemente, no s�lo est� indisponible por alguna raz�n desconocida como con 404. (Nuevo en HTTP 1.1)
411 Length Required El servidor no puede procesar la petici�n a menos que el cliente env�e una cabecera Content-Length. (Nuevo en HTTP 1.1)
412 Precondition Failed Alguna condici�n pr�via especificada en la petici�n era falsa (Nuevo en HTTP 1.1)
413 Request Entity Too Large El documento pedido es mayor que lo que el servidor quiere manejar ahora. Si el servidor cree que puede manejarlo m�s tarde, deber�a incluir una cabecera Retry-After. (Nuevo en HTTP 1.1)
414 Request URI Too Long La URI es demsiado larga. (Nuevo en HTTP 1.1)
415 Unsupported Media Type La petici�n est� en un formato desconocido. (Nuevo en HTTP 1.1)
416 Requested Range Not Satisfiable El cliente incluy� una cabecera Range no satisfactoria en la petici�n. (Nuevo en HTTP 1.1)
417 Expectation Failed No se puede conseguir el valor de la cabecera Expect. (Nuevo en HTTP 1.1)
500 Internal Server Error Mensaje gen�rico "server is confused". Normalmente es el resultado de programas CGI o servlets que se quedan colgados o retornan cabeceras mal formateadas.
501 Not Implemented El servidor no soporta la funcionalidad de rellenar peticiones. Usado, por ejemplo, cuando el cliente env�a comandos como PUT que el cliente no soporta.
502 Bad Gateway Usado por servidores que act�an como proxies o gateways; indica que el servidor inicial obtuvo una mala respuesta desde el servidor remoto.
503 Service Unavailable El servidor no puede responder debido a mentenimiento o sobrecarga. Por ejemplo, un servlet podr�a devolver esta cabecera si alg�n almacen de threads o de conexiones con bases de datos est�n llenos. El servidor puede suministrar una cabecera Retry-After.
504 Gateway Timeout Usado por servidores que act�an como proxies o gateways; indica que el servidor inicial no obtuvo una respuesta a tiempo del servidor remoto. (Nuevo en HTTP 1.1)
505 HTTP Version Not Supported El servidor no soporta la versi�n de HTTP indicada en la l�nea de petici�n. (Nuevo en HTTP 1.1)

.�Ejemplo: Motor de B�squeda

Aqu� tenemos un ejemplo que hace uso de los dos c�digos de estado m�s comunes distintos de 200: 302 y 404. El c�digo 302 se selecciona mediante el m�todo sendRedirect, y 404 se selecciona mediante sendError.

En esta aplicaci�n, primero un formulario HTML muestra una p�gina que permite al usuario elegir una cadena de b�squeda, el n�mero de los resultados por p�gina, y el motor de b�squeda a utilizar. Cuando se env�a el formulario, el servlet extrae estos tres par�metros, construye una URL con los par�metros embebidos en una forma apropiada para el motor de b�squeda seleccionado, y redirige al usuario a esa direcci�n. Si el usuario falla al elegir el motor de b�squeda o env�a un nombre de motor de b�squeda no conocido, se devuelve una p�gina de error 404 diciendo que no hay motor de b�squeda o que no se conoce.

.�SearchEngines.java

Puedes descargar el c�digo fuente.

Nota: hace uso de la clase SearchSpec, mostrada abajo, que incorpora informaci�n sobre como construir URLs para realizar b�squedas en varios buscadores.

package hall;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.net.*;

public class SearchEngines extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    // The URLEncoder changes spaces to "+" signs and other
    // non-alphanumeric characters to "%XY", where XY is the
    // hex value of the ASCII (or ISO Latin-1) character.
    // The getParameter method decodes automatically, but since
    // we're just passing this on to another server, we need to
    // re-encode it.
    String searchString =
      URLEncoder.encode(request.getParameter("searchString"));
    String numResults =
      request.getParameter("numResults");
    String searchEngine =
      request.getParameter("searchEngine");
    SearchSpec[] commonSpecs = SearchSpec.getCommonSpecs();
    for(int i=0; i<commonSpecs.length; i++) {
      SearchSpec searchSpec = commonSpecs[i];
      if (searchSpec.getName().equals(searchEngine)) {
        // encodeURL is just planning ahead in case this servlet
        // is ever used in an application that does session tracking.
        // If cookies are turned off, session tracking is usually
        // accomplished by URL rewriting, so all URLs returned
        // by servlets should be sent through encodeURL.
        String url =
          response.encodeURL(searchSpec.makeURL(searchString,
                                                 numResults));
        response.sendRedirect(url);
        return;
      }
    }
    response.sendError(response.SC_NOT_FOUND,
                       "No recognized search engine specified.");
  }

  public void doPost(HttpServletRequest request,
                     HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}

.�SearchSpec.java

package hall;

class SearchSpec {
  private String name, baseURL, numResultsSuffix;

  private static SearchSpec[] commonSpecs =
    { new SearchSpec("google",
                     "http://www.google.com/search?q=",
                     "&num="),
      new SearchSpec("infoseek",
                     "http://infoseek.go.com/Titles?qt=",
                     "&nh="),
      new SearchSpec("lycos",
                     "http://lycospro.lycos.com/cgi-bin/pursuit?query=",
                     "&maxhits="),
      new SearchSpec("hotbot",
                     "http://www.hotbot.com/?MT=",
                     "&DC=")
    };

  public SearchSpec(String name,
                    String baseURL,
                    String numResultsSuffix) {
    this.name = name;
    this.baseURL = baseURL;
    this.numResultsSuffix = numResultsSuffix;
  }

  public String makeURL(String searchString, String numResults) {
    return(baseURL + searchString + numResultsSuffix + numResults);
  }

  public String getName() {
    return(name);
  }

  public static SearchSpec[] getCommonSpecs() {
    return(commonSpecs);
  }
}

.�SearchSpec.java

Pulsa con el bot�n derecho sobre el enlace al c�digo fuente para descargar el fichero fuente.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
  <TITLE>Searching the Web</TITLE>
</HEAD>

<BODY BGCOLOR="#FDF5E6">
<H1 ALIGN="CENTER">Searching the Web</H1>

<FORM ACTION="/servlet/hall.SearchEngines">
  <CENTER>
    Search String: 
    <INPUT TYPE="TEXT" NAME="searchString"><BR>
    Results to Show Per Page:
    <INPUT TYPE="TEXT" NAME="numResults" 
                       VALUE=10 SIZE=3><BR>
    <INPUT TYPE="RADIO" NAME="searchEngine"
                        VALUE="google">
    Google |
    <INPUT TYPE="RADIO" NAME="searchEngine"
                        VALUE="infoseek">
    Infoseek |
    <INPUT TYPE="RADIO" NAME="searchEngine"
                        VALUE="lycos">
    Lycos |
    <INPUT TYPE="RADIO" NAME="searchEngine"
                        VALUE="hotbot">
    HotBot
    <BR>
    <INPUT TYPE="SUBMIT" VALUE="Search">
  </CENTER>
</FORM>

</BODY>
</HTML>

.�Pantalla inicial

Pantalla Inicial

.�Resultados de la Busqueda

Resultados de la busqueda

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR