servlet httpservlet example ejemplo java http servlets

java - example - Ordenamiento de valores en HttpServletRequest.getParameterValues()



servlet http request (5)

De hecho, no está definido explícitamente en la especificación Servlet, pero al menos la especificación de formularios HTML lo define explícitamente en la sección application/x-www-form-urlencoded :

2.Los nombres / valores de los controles se enumeran en el orden en que aparecen en el documento.

Entonces, esa parte es segura. Ahora, el servletcontainer, lo más lógicamente posible: una implementación decente y eficiente procesaría el flujo de entrada HTTP de inmediato a medida que se recibe, por lo que los parámetros se procesarán en el orden en que aparecen en el URI de solicitud (GET) o el cuerpo de solicitud (POST). Recolectarlos en una String[] es la opción más sencilla, ya que también se usa tal como está en la API de Servlet, así que realmente no veo ninguna razón para recopilarla en una estructura similar a HashSet , o hacer una recopilación Collections#shuffle() o lo que sea y luego convertirlo a String[] después.

Por lo menos puedo decir por experiencia, que Tomcat lo hace de la manera correcta, por lo que todos los principales contenedores / servidores de aplicaciones que se construyen sobre Tomcat / Catalina (IBM Websphere, JBoss AS, Sun Glassfish, etc.) también se comportarán de esa manera. Solo no tengo experiencia práctica con Weblogic, pero me sorprendería si lo procesa de manera diferente (leer: menos eficiente).

Solo el orden de los nombres de los parámetros no está garantizado, lógicamente porque está respaldado por un HashMap .

Resumido: los parámetros se recopilan en un HashMap<String, String[]> . Los nombres se garantizan y no se ordenan debido a la naturaleza del HashMap . Los valores (un nombre de parámetro puede tener varios valores, por ejemplo, foo=bar1&foo=bar2&foo=bar3 ) están ordenados debido a la naturaleza de la String[] , aunque esto no se especifica explícitamente en la API de Servlet.

Para estar seguro, le gustaría usar un enfoque diferente, por ejemplo,

foos=3&foo[0]=bar1&foo[1]=bar2&foo[2]=bar3

con

int foos = Integer.valueOf(request.getParameter("foos")); for (int i = 0; i < foos; i++) { int foo = Integer.valueOf(request.getParameter("foo[" + i + "]")); }

HttpServletRequest.getParameterValues() devuelve una String[] contiene todos los valores de un parámetro de solicitud HTTP dado. ¿Alguien sabe si el orden de los valores en esta matriz está garantizado por la especificación al igual que el orden por el cual esos valores se pasaron en la solicitud?

Por ejemplo, si tengo la cadena de consulta GET x=1&x=2&x=3 , ¿tengo la garantía de recibir la String[] {"1", "2", "3"} cuando llame a getParameterValues() ? Parece funcionar en la práctica, pero no puedo encontrar nada que especifique que este debe ser el caso, por lo que me resisto a confiar en ello.


Depende de la implementación de la interfaz HttpServletRequest.


El javadoc para ServletRequest ( v2.5 javadoc ) no menciona nada sobre el orden de los valores para ese método. Como tal, no confiaría en que el orden fuera preservado.

Actualización: también verificó el documento de especificaciones para 2.5, contiene la siguiente información relacionada con getParameterValues ​​(). No menciona nada sobre el orden con respecto a la cadena de consulta, por lo que creo que el comportamiento que está viendo es el detalle de la implementación, no definido como parte de la interfaz.

Los parámetros se almacenan como un conjunto de pares nombre-valor. Pueden existir múltiples valores de parámetros para cualquier nombre de parámetro dado. Los siguientes métodos de la interfaz ServletRequest están disponibles para acceder a los parámetros:

  • getParameter
  • getParameterNames
  • getParameterValues
  • getParameterMap

El método getParameterValues ​​devuelve una matriz de objetos String que contienen todos los valores de parámetros asociados con un nombre de parámetro. El valor devuelto por el método getParameter debe ser el primer valor en la matriz de objetos String devueltos por getParameterValues. El método getParameterMap devuelve un java.util.Map del parámetro de la solicitud, que contiene nombres como claves y valores de parámetros como valores de mapa.

Para futuras referencias, las especificaciones de Java Servlet se pueden descargar de Sun, me refiero al sitio web de Oracle . Puedes revisar la versión específica del servlet en la que estás interesado.


Sí, el orden de los valores devueltos por getParamterValues(String) y las entradas en getParameterMap() están garantizados por la especificación Servlet. Aquí está el pasaje:

Los datos de la cadena de consulta y el cuerpo de la publicación se agregan al conjunto de parámetros de solicitud. Los datos de cadena de consulta se presentan antes de los datos del cuerpo de la publicación. Por ejemplo, si se realiza una solicitud con una cadena de consulta de a = hola y un cuerpo de publicación de a = adiós y a = mundo, el conjunto de parámetros resultante se ordenaría a = (hola, adiós, mundo).

(Esto es de la sección "Parámetros del Protocolo HTTP" dentro del capítulo "La Solicitud" de las Especificaciones del Servlet (SRV.4.1 en la versión 2.4, SRV.3.1 en la versión 2.5).)

No parece haber una forma limpia de ordenar los nombres ( getParameterNames() no devuelve los nombres en el orden en que se dio el navegador). Supongo que podría analizar la cadena GET sin procesar de getQueryString() o analizar la cadena POST sin procesar de getInputStream() , pero en cambio creo que getParameterValues(String) otro parámetro oculto y luego getParameterValues(String) para obtener su orden.

Si tiene curiosidad por saber por qué quiero los parámetros en orden, es porque tengo controles que el usuario puede reorganizar usando jQuery, y quiero saber el orden que el usuario ha elegido:

<form> <ul id=variables> <li> <input name=hello>hello <input type=hidden name=variableOrder value=hello> <li> <input name=world>world <input type=hidden name=variableOrder value=world> </ul> </form> <script src="jquery.js"></script> <script src="jquery-ui.js"></script> <script> jQuery(''#variables'').sortable().disableSelection(); </script>


Tengo un problema para extraer el mapa param-value de HttpServletRequest en orden de acuerdo con los elementos en el JSP. Escribí un OrderedRequestMap que analiza un cuerpo de solicitud POST de aplicación / x-www-form-urlencoded.

import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; public class OrderedRequestMap extends LinkedHashMap<String,String[]> { private final String encoding; public OrderedRequestMap(InputStream httpBody, String encoding) throws IOException { this.encoding = encoding; fill(httpBody); } private void fill(InputStream is) throws IOException { final InputStreamReader reader = new InputStreamReader(is, "ASCII"); int c; StringBuilder sb = new StringBuilder(1000); while ((c = reader.read()) != -1) { char ch = (char)c; if (ch == ''&'') { put(sb.toString()); sb = new StringBuilder(1000); } else { sb.append(ch); } } put(sb.toString()); } private void put(String parameter) throws UnsupportedEncodingException { String[] pair = parameter.split("="); if (pair.length == 0 ) return; String key = URLDecoder.decode(pair[0], encoding); String val = EMPTY_STR; if (pair.length > 1) val = URLDecoder.decode(pair[1], encoding); String[] values = get(key); if (values == null) values = new String[]{val}; else { values = Arrays.copyOf(values, values.length+1); values[values.length - 1] = val; } put(key, values); } private static final String EMPTY_STR = ""; }

Y llamalo asi

new OrderedRequestMap(request.getInputStream(), request.getCharacterEncoding());

Espero eso ayude.