Si alguna vez has usado un motor de b�squeda Web, visitado un tienda de libros on-line, etc., probablemente habr�s encontrado URLs de b�squeda divertidas como http://host/path?user=Marty+Hall&origin=bwi&dest=lax. La parte posterior a la interrogaci�n (user=Marty+Hall&origin=bwi&dest=lax) es conocida como datos de formulario, y es la forma m�s com�n de obtener datos desde una p�gina Web para un programa del lado del servidor. Puede a�adirse al final de la URL despu�s de la interrogaci�n (como arriba) para peticiones GET o enviada al servidor en una l�nea separada, para peticiones POST.
Extraer la informaci�n necesaria desde estos datos de formulario es tradicionalmente una de las partes m�s tediosas de la programaci�n CGI
Primero de todo, tenemos que leer los datos de una forma para las peticiones GET (en CGI tradicional, esto se hace mediante QUERY_STRING), y de otra forma para peticiones POST (normalmente leyendo la entrada est�ndard).
Segundo, tenemos que separar las parejas de los ampersands, luego separar los nombres de los par�metros (a la izquierda de los signos igual) del valor del par�metro (a la derecha de los signos igual).
Tercero, tenemos que decodificar los valores. Los valores alfanum�ricos no cambian, pero los espacios son convertidos a signos m�s y otros caracteres se convierten como %XX donde XX es el valor ASCII (o ISO Latin-1) del car�cter, en hexadecimal. Por ejemplo, si alguien introduce un valor de "~hall, ~gates, y ~mcnealy" en un campo de texto con el nombre "users" en un formulario HTML, los datos ser�an enviados como "users=%7Ehall%2C+%7Egates%2C+and+%7Emcnealy".
Finalmente, la cuarta raz�n que hace que el an�lisis de los datos de formulario sea tedioso es que los valores pueden ser omitidos (por ejemplo, param1=val1¶m2=¶m3=val3) y un par�metro puede tener m�s de un valor y que el mismo par�metro puede aparecer m�s de una vez (por ejemplo: param1=val1¶m2=val2¶m1=val3).
Una de las mejores caracter�sticas de los servlets Java es que todos estos an�lisis de formularios son manejados autom�ticamente. Simplemente llamamos al m�todo getParameter de HttpServletRequest, y suministramos el nombre del par�metro como un argumento. Observa que los nombres de par�metros son sensibles a la may�sculas. Hacemos esto exactamente igual que cuando los datos son enviados mediante GET o como si los enviaramos mediante POST. El valor de retorno es un String correspondiente al valor uudecode de la primera ocurrencia del par�metro. Se devuelve un String vac�o si el par�metro existe pero no tiene valor, y se devuelve null si no existe dicho par�metro. Si el par�metro pudiera tener m�s de un valor, como en el ejemplo anterior, deber�amos llamar a getParameterValues en vez de a getParameter. Este devuelve un array de strings. Finalmente, aunque en aplicaciones reales nuestros servlets probablemente tengan un conjunto espec�fico de nombres de par�metros por los que buscar. Usamos getParameterNames para esto, que devuelve una Enumeration, cada entrada puede ser forzada a String y usada en una llamada a getParameter.
�Ejemplo: Leer Tres Par�metros
Aqu� hay un sencillo ejemplo que lee tres par�metros llamados param1, param2, y param3, listando sus valores en una lista marcada. Observamos que, aunque tenemos que especificar selecciones de respuesta (content type, status line, otras cabeceras HTTP) antes de empezar a generar el contenido, no es necesario que leamos los par�metros de petici�n en un orden particular.
Tambi�n observamos que podemos crear f�cilmente servlets que puedan manejar datos GET y POST, simplemente haciendo que su m�todo doPost llame a doGet o sobreescribiendo service (que llama a doGet, doPost, doHead, etc.). Esta es una buena pr�ctica est�ndard, ya que requiere muy poco trabajo extra y permite flexibilidad en el lado del cliente. Si hemos usado la aproximaci�n CGI tradicional cuando leemos los datos POST mediante la entrada est�ndard. Deber�amos observar que hay una forma similar con los Servlets llamando primero a getReader o getInputStream sobre HttpServletRequest. Esto es una mala idea para par�metros normales, pero podr�a usarse para ficheros descargados o datos POST que est�n siendo enviados por clientes personales en vez de formularios HTML. Observa, sin embargo, que si leemos los datos POST de esta manera, podr�an no ser encontrados por getParameter.
�ThreeParams.java
Tambi�n puedes descargar el c�digo fuente. Nota: tambi�n usa
ServletUtilities.java, mostrado anteriormente.
package hall; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class ThreeParams extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Reading Three Request Parameters"; out.println(ServletUtilities.headWithTitle(title) + "<BODY>\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<UL>\n" + " <LI>param1: " + request.getParameter("param1") + "\n" + " <LI>param2: " + request.getParameter("param2") + "\n" + " <LI>param3: " + request.getParameter("param3") + "\n" + "</UL>\n" + "</BODY></HTML>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
�Salida de ThreeParams

�Ejemplo: Listar todos los Datos del Formulario
Aqu� hay un ejemplo que busca todos los nombres de par�metros que fueron enviados y los pone en una tabla. Ilumina los par�metros que tienen valor cero as� como aquellos que tienen m�ltiples valores.
Primero busca todos los nombres de par�metros mediante el m�todo getParameterNames de HttpServletRequest. Esto devuelve una Enumeration. Luego, pasa por la Enumeration de la forma est�ndard, usando hasMoreElements para determinar cuando parar y usando nextElement para obtener cada entrada. Como nextElement devuelve un Object, fuerza el resultado a String y los pasa a getParameterValues, obteniendo un array de Strings. Si este array s�lo tiene una entrada y s�lo contiene un string vac�o, el par�metro no tiene valores, y el servlet genera una entrada "No Value" en it�lica. Si el array tiene m�s de una entrada, el par�metro tiene m�ltiples valores, y se muestran en una lista bulleteada. De otra forma, el �nico valor principal se s�tua en la tabla.
�ShowParameters.java
Tambi�n puedes descargar el c�digo fuente. Nota: tambi�n usa
ServletUtilities.java, mostrado anteriormente.
package hall; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; /** Shows all the parameters sent to the servlet via either * GET or POST. Specially marks parameters that have no values or * multiple values. * * Part of tutorial on servlets and JSP that appears at * http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/ * 1999 Marty Hall; may be freely used or adapted. */ public class ShowParameters extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Reading All Request Parameters"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Parameter Name<TH>Parameter Value(s)"); Enumeration paramNames = request.getParameterNames(); while(paramNames.hasMoreElements()) { String paramName = (String)paramNames.nextElement(); out.println("<TR><TD>" + paramName + "\n<TD>"); String[] paramValues = request.getParameterValues(paramName); if (paramValues.length == 1) { String paramValue = paramValues[0]; if (paramValue.length() == 0) out.print("<I>No Value</I>"); else out.print(paramValue); } else { out.println("<UL>"); for(int i=0; i<paramValues.length; i++) { out.println("<LI>" + paramValues[i]); } out.println("</UL>"); } } out.println("</TABLE>\n</BODY></HTML>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
�ShowParameters
Aqu� tenemos un formulario HTML que env�a un n�mero de par�metros a este servlet. Pulsa con el bot�n derecho sobre el enlace al c�digo fuente para descargar el HTML.
Usa POST para enviar los datos (como deber�an hacerlo todos los formularios que tienen entradas PASSWORD), demonstrando el valor de que los servlets incluyan tanto doGet como doPost.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>A Sample FORM using POST</TITLE> </HEAD> <BODY BGCOLOR="#FDF5E6"> <H1 ALIGN="CENTER">A Sample FORM using POST</H1> <FORM ACTION="/servlet/hall.ShowParameters" METHOD="POST"> Item Number: <INPUT TYPE="TEXT" NAME="itemNum"><BR> Quantity: <INPUT TYPE="TEXT" NAME="quantity"><BR> Price Each: <INPUT TYPE="TEXT" NAME="price" VALUE="$"><BR> <HR> First Name: <INPUT TYPE="TEXT" NAME="firstName"><BR> Last Name: <INPUT TYPE="TEXT" NAME="lastName"><BR> Middle Initial: <INPUT TYPE="TEXT" NAME="initial"><BR> Shipping Address: <TEXTAREA NAME="address" ROWS=3 COLS=40></TEXTAREA><BR> Credit Card:<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Visa">Visa<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Master Card">Master Card<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Amex">American Express<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Discover">Discover<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Java SmartCard">Java SmartCard<BR> Credit Card Number: <INPUT TYPE="PASSWORD" NAME="cardNum"><BR> Repeat Credit Card Number: <INPUT TYPE="PASSWORD" NAME="cardNum"><BR><BR> <CENTER> <INPUT TYPE="SUBMIT" VALUE="Submit Order"> </CENTER> </FORM> </BODY> </HTML>

�Resultados del env�o
