Análisis de cadenas de consulta en Android

271

Java EE tiene ServletRequest.getParameterValues ​​() .

En plataformas que no son EE, URL.getQuery () simplemente devuelve una cadena.

¿Cuál es la forma normal de analizar correctamente la cadena de consulta en una URL cuando no está en Java EE?


< despotricar >

Es popular en las respuestas intentar hacer su propio analizador. Este es un proyecto de microcodificación muy interesante y emocionante, pero no puedo decir que sea una buena idea :(

Los fragmentos de código a continuación son generalmente defectuosos o rotos, por cierto. Romperlos es un ejercicio interesante para el lector. Y a los piratas informáticos que atacan los sitios web que los utilizan .

Analizar cadenas de consulta es un problema bien definido, pero leer las especificaciones y comprender los matices no es trivial. ¡Es mucho mejor dejar que un codificador de la biblioteca de la plataforma haga el trabajo duro y arregle el problema por usted!

< / rant >

Será
fuente
¿Podría publicar una URL de muestra, de qué está obteniendo getQuery()y qué desea obtener como salida?
Thomas Owens el
1
¿Desea hacer esto desde un servlet o una página JSP? Necesito alguna aclaración antes de responder.
ChadNC el
1
¿También necesita analizar los parámetros POST?
Thilo el
2
Incluso si está en J2EE (o en SE con paquetes EE seleccionados agregados a través de OSGi, como yo), esta pregunta podría tener sentido. En mi caso, las cadenas de consulta / cuerpos POST codificados en url son procesados ​​por una parte del sistema que es intencionalmente independiente de cosas como ServletRequest.
Hanno Fietz
61
¡Votaron por <rant />!
Nowaker

Respuestas:

65

Desde Android M las cosas se han vuelto más complicadas. La respuesta de android.net.URI .getQueryParameter () tiene un error que rompe espacios antes de JellyBean. Apache URLEncodedUtils.parse () trabajó, pero fue en desuso en L , y elimina en M .

Entonces la mejor respuesta ahora es UrlQuerySanitizer . Esto ha existido desde el nivel 1 de API y todavía existe. También te hace pensar en cuestiones difíciles como cómo manejas caracteres especiales o valores repetidos.

El código más simple es

UrlQuerySanitizer.ValueSanitizer sanitizer = UrlQuerySanitizer.getAllButNullLegal();
// remember to decide if you want the first or last parameter with the same name
// If you want the first call setPreferFirstRepeatedParameter(true);
sanitizer.parseUrl(url);
String value = sanitizer.getValue("paramName"); // get your value

Si está satisfecho con el comportamiento de análisis predeterminado, puede hacer lo siguiente:

new UrlQuerySanitizer(url).getValue("paramName")

pero debe asegurarse de comprender cuál es el comportamiento de análisis predeterminado, ya que podría no ser lo que desea.

Nick Fortescue
fuente
44
URLQuerySanitizer.getAllButNullLegal () devuelve UrlQuerySanitizer.ValueSanitizer, no UrlQuerySanitizer.
Peter Zhao
31
Por alguna razón, lo anterior no funcionó para mí, tuve que modificarlo ligeramente, lo que lo hace aún más fácil:UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL); String value = sanitizer.getValue("parameter");
SeBsZ
3
No trabajo. UrlQuerySanitizer en sdk-23 solo tiene un métodosanitize()
Ninja el
Esto decodificará caracteres especiales y emoji para _. Tuve que ir con stackoverflow.com/a/35638979/1155282
Irshu
¿Hay una biblioteca equivalente de Spring Framework de esto?
iamjoshua el
202

En Android:

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");
diyism
fuente
20
tenga en cuenta que esto usa la clase Uri y no la clase URI (Uri es parte de android.net, mientras que URI es parte de java.net)
Marius
55
También tenga en cuenta que antes de Ice Cream Sandwich, esto no puede analizar caracteres + en valores a un carácter de espacio.
Rpetrich
@rpetrich en realidad los documentos dicen que el error es anterior a Jelly Bean, incluido Ice Cream Sandwich. ref
Big McLargeHuge
64

En Android, las bibliotecas de Apache proporcionan un analizador de consultas:

http://developer.android.com/reference/org/apache/http/client/utils/URLEncodedUtils.html y http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/ http / client / utils / URLEncodedUtils.html

Será
fuente
9
Está disponible en la biblioteca del cliente http apache, no solo en Android. Por cierto, el enlace a apache fue cambiado. La última es: hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…
Cristian Vrabie
9
Molestamente URLEncodedUtils.parse()devuelve un Listque luego tendría que recorrer para encontrar el valor de una clave específica. Sería mucho mejor si devolviera un me Mapgusta en la respuesta de BalusC.
Asaph
1
@Hanno Fietz, ¿quieres decir que confías en estas alternativas? Sé que tienen errores. Sé que señalar los errores que veo solo alentará a las personas a adoptar versiones 'fijas', en lugar de buscar los errores que he pasado por alto.
Será
1
@Will: bueno, nunca confiaría en los fragmentos de copiar y pegar que obtuve de cualquier sitio web, y nadie debería hacerlo. Pero aquí, estos fragmentos están bastante bien revisados ​​y comentados y, por arelo tanto, son realmente útiles. Simplemente ver algunas sugerencias sobre lo que podría estar mal con el código ya es una gran ayuda para pensar por mí mismo. Y fíjate, no quise decir "rodar el tuyo es mejor", sino que es bueno tener un buen material para una decisión informada en mi propio código.
Hanno Fietz
8
Me imagino que parse devuelve una lista para que mantenga el orden posicional y permita más fácilmente entradas duplicadas.
dhaag23
26

Aquí está la respuesta de BalusC , pero compila y devuelve resultados:

public static Map<String, List<String>> getUrlParameters(String url)
        throws UnsupportedEncodingException {
    Map<String, List<String>> params = new HashMap<String, List<String>>();
    String[] urlParts = url.split("\\?");
    if (urlParts.length > 1) {
        String query = urlParts[1];
        for (String param : query.split("&")) {
            String pair[] = param.split("=");
            String key = URLDecoder.decode(pair[0], "UTF-8");
            String value = "";
            if (pair.length > 1) {
                value = URLDecoder.decode(pair[1], "UTF-8");
            }
            List<String> values = params.get(key);
            if (values == null) {
                values = new ArrayList<String>();
                params.put(key, values);
            }
            values.add(value);
        }
    }
    return params;
}
dfrankow
fuente
1
Nota de JVM: He implementado una forma equivalente de esto en Scala usando Colecciones Java; Aquí está la esencia de Github: gist.github.com/3504765
Jay Taylor
2
I sugerir cambiar String pair[] = param.split("=");en String pair[] = param.split("=", 2);dividir la clave = valor par sólo en la primera ocurrencia. Creo que está permitido tener signos iguales sin codificar en el valor.
Dennie
22

Si tiene librerías jetty (servidor o cliente) en su classpath, puede usar las clases jetty util (consulte javadoc ), por ejemplo:

import org.eclipse.jetty.util.*;
URL url = new URL("www.example.com/index.php?foo=bar&bla=blub");
MultiMap<String> params = new MultiMap<String>();
UrlEncoded.decodeTo(url.getQuery(), params, "UTF-8");

assert params.getString("foo").equals("bar");
assert params.getString("bla").equals("blub");
Moritz
fuente
13

Si está utilizando Spring 3.1 o superior (vaya, esperaba que el soporte retrocediera más), puede usar UriComponentsy UriComponentsBuilder:

UriComponents components = UriComponentsBuilder.fromUri(uri).build();
List<String> myParam = components.getQueryParams().get("myParam");

components.getQueryParams() devuelve un MultiValueMap<String, String>

Aquí hay más documentación .

Nick Spacek
fuente
Esto es algo que estoy buscando. Mi pregunta es ¿cómo obtengo el uri? Estoy atascado con el mantenimiento del código que no puedo cambiar mucho y no estamos usando HttpServlet. En su lugar, solo use anotaciones y Spring (@Get, @Produces (mediaType) y @Path ("/ dataAsJSON / datafield / {datafield})) Solo necesito saber cómo obtener la cadena de consulta para poder analizarla como se muestra en este ejemplo.
Nelda.techspiress
5

Para un servlet o una página JSP, puede obtener pares clave / valor de cadena de consulta utilizando request.getParameter ("paramname")

String name = request.getParameter("name");

Hay otras formas de hacerlo, pero así es como lo hago en todos los servlets y páginas jsp que creo.

ChadNC
fuente
3
HttpServletRequest es parte de J2EE que no tiene. Además, usar getParamter () no está realmente analizando.
Mr. Shiny and New 安 宇
3
Tómese el tiempo para leer el comentario en el que solicité una aclaración de su pregunta. Esta respuesta es en respuesta a su respuesta a ese comentario en el que dijo: "Estoy tratando de hacer esto en Android, pero todas las respuestas en todas las plataformas serían respuestas útiles que podrían dar consejos (también a otros que podrían encontrar esto) pregunta) así que no te detengas! " Respondí su pregunta a partir de ese comentario. Si no tiene nada útil que agregar, no agregue nada
ChadNC el
1
No te enfades demasiado. "Esto no responde la pregunta" es útil para agregar, OMI.
Mr. Shiny and New 安 宇
1
No importa Android o no, la pregunta es cómo analizar la cadena que contiene la URL y obtener los parámetros de la URL. Lo que está transfiriendo aquí es parte de la API de Servlet, donde el contenedor de Servlet analiza los parámetros entrantes de la solicitud HTTP por usted. Es irrelevante, porque la pregunta es sobre analizar String que contiene URL, no una solicitud HTTP, y no dentro del contenedor Servlet.
mvmn
5

En Android, traté de usar la respuesta @diyism pero encontré el problema de caracteres espaciales planteado por @rpetrich, por ejemplo: lleno un formulario donde username = "us+us"y hago password = "pw pw"que una cadena de URL se vea así:

http://somewhere?username=us%2Bus&password=pw+pw

Sin embargo, el código @diyism regresa "us+us"y "pw+pw", es decir, no detecta el carácter de espacio. Si la URL se reescribió con %20el carácter de espacio se identifica:

http://somewhere?username=us%2Bus&password=pw%20pw

Esto lleva a la siguiente solución:

Uri uri = Uri.parse(url_string.replace("+", "%20"));
uri.getQueryParameter("para1");
Stephen Quan
fuente
replace(" ", "%20")Esto se siente mal. Pero hizo el truco para mí: D
Mārtiņš Briedis
La sintaxis correcta debe ser "alguna cadena" .replaceAll ("[+]", "% 20");
RRTW
4

Analizar la cadena de consulta es un poco más complicado de lo que parece, dependiendo de cuán indulgente quieras ser.

Primero, la cadena de consulta son bytes ascii. Usted lee estos bytes uno a la vez y los convierte en caracteres. Si el personaje es? o & luego indica el inicio de un nombre de parámetro. Si el carácter es =, entonces señala el inicio de un valor de parámetro. Si el carácter es%, indica el inicio de un byte codificado. Aquí es donde se pone difícil.

Cuando lee en un% char, debe leer los siguientes dos bytes e interpretarlos como dígitos hexadecimales. Eso significa que los siguientes dos bytes serán 0-9, af o AF. Pegue estos dos dígitos hexadecimales para obtener su valor de byte. Pero recuerda, los bytes no son caracteres . Debe saber qué codificación se usó para codificar los caracteres. El carácter é no codifica lo mismo en UTF-8 que en ISO-8859-1. En general, es imposible saber qué codificación se usó para un conjunto de caracteres dado. Siempre uso UTF-8 porque mi sitio web está configurado para servir siempre todo usando UTF-8, pero en la práctica no puede estar seguro. Algunos agentes de usuario le indicarán la codificación de caracteres en la solicitud; puede intentar leer eso si tiene una solicitud HTTP completa. Si solo tienes una url aislada, buena suerte.

De todos modos, suponiendo que está utilizando UTF-8 o alguna otra codificación de caracteres de varios bytes, ahora que ha decodificado un byte codificado, debe dejarlo a un lado hasta que capture el siguiente byte. Necesita todos los bytes codificados que están juntos porque no puede decodificar url correctamente un byte a la vez. Ponga a un lado todos los bytes que están juntos y luego descifrelos todos a la vez para reconstruir su personaje.

Además, se vuelve más divertido si quieres ser indulgente y tener en cuenta a los agentes de usuario que destruyen las URL. Por ejemplo, algunos clientes de correo web codifican dos cosas. O duplique los caracteres? & = (Por ejemplo:) http://yoursite.com/blah??p1==v1&&p2==v2. Si desea tratar de resolverlo con gracia, deberá agregar más lógica a su analizador.

Sr. Brillante y Nuevo 安 宇
fuente
Eso no explica cómo analizar o recuperar los valores de los parámetros de la cadena de consulta
ChadNC
Correcto, pero un poco engorroso. Para eso ya tenemos URLDecoder.
BalusC
2
@ChadNC: la tercera oración le dice cómo analizar: leer en un byte a la vez y convertir en caracteres. La cuarta oración te advierte de caracteres especiales. Etc. ¿Tal vez no leíste la respuesta?
Mr. Shiny and New 安 宇
@BalusC: URLDecoder funciona, pero tiene algunos modos de falla si está tratando de ser más indulgente con el tipo de URL que acepta.
Mr. Shiny and New 安 宇
1
Estar de acuerdo con @ Mr.ShinyAndNew parse query param no es fácil. Estoy apoyando FIQL y esto se convierte en un verdadero dolor de cabeza. Por ejemplo: yoursite.com/blah??p1==v1&&p2==v2,p2==v3;p2==v4
rafa.ferreira
4

En Android es simple como el código a continuación:

UrlQuerySanitizer sanitzer = new UrlQuerySanitizer(url);
String value = sanitzer.getValue("your_get_parameter");

Además, si no desea registrar cada clave de consulta esperada, use:

sanitzer.setAllowUnregisteredParamaters(true)

Antes de llamar:

sanitzer.parseUrl(yourUrl)
Kevin Crain
fuente
4

Tengo métodos para lograr esto:

1) :

public static String getQueryString(String url, String tag) {
    String[] params = url.split("&");
    Map<String, String> map = new HashMap<String, String>();
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }

    Set<String> keys = map.keySet();
    for (String key : keys) {
        if(key.equals(tag)){
         return map.get(key);
        }
        System.out.println("Name=" + key);
        System.out.println("Value=" + map.get(key));
    }
    return "";
}

2) y la forma más fácil de hacer esto usando la clase Uri :

public static String getQueryString(String url, String tag) {
    try {
        Uri uri=Uri.parse(url);
        return uri.getQueryParameter(tag);
    }catch(Exception e){
        Log.e(TAG,"getQueryString() " + e.getMessage());
    }
    return "";
}

y este es un ejemplo de cómo usar cualquiera de los dos métodos:

String url = "http://www.jorgesys.com/advertisements/publicidadmobile.htm?position=x46&site=reform&awidth=800&aheight=120";      
String tagValue = getQueryString(url,"awidth");

el valor de tagValue es 800

Jorgesys
fuente
3

En Android, puede usar el método estático Uri.parse de la clase android.net.Uri para hacer el trabajo pesado. Si está haciendo algo con URI e Intentos, querrá usarlo de todos modos.

Patrick O'Leary
fuente
3

Solo como referencia, esto es con lo que terminé (basado en URLEncodedUtils, y devolviendo un Mapa).

caracteristicas:

  • acepta la parte de la cadena de consulta de la url (puede usar request.getQueryString())
  • una cadena de consulta vacía producirá un vacío Map
  • un parámetro sin un valor (? prueba) se asignará a un vacío List<String>

Código:

public static Map<String, List<String>> getParameterMapOfLists(String queryString) {
    Map<String, List<String>> mapOfLists = new HashMap<String, List<String>>();
    if (queryString == null || queryString.length() == 0) {
        return mapOfLists;
    }
    List<NameValuePair> list = URLEncodedUtils.parse(URI.create("http://localhost/?" + queryString), "UTF-8");
    for (NameValuePair pair : list) {
        List<String> values = mapOfLists.get(pair.getName());
        if (values == null) {
            values = new ArrayList<String>();
            mapOfLists.put(pair.getName(), values);
        }
        if (pair.getValue() != null) {
            values.add(pair.getValue());
        }
    }

    return mapOfLists;
}

Un asistente de compatibilidad (los valores se almacenan en una matriz de cadenas al igual que en ServletRequest.getParameterMap () ):

public static Map<String, String[]> getParameterMap(String queryString) {
    Map<String, List<String>> mapOfLists = getParameterMapOfLists(queryString);

    Map<String, String[]> mapOfArrays = new HashMap<String, String[]>();
    for (String key : mapOfLists.keySet()) {
        mapOfArrays.put(key, mapOfLists.get(key).toArray(new String[] {}));
    }

    return mapOfArrays;
}
Dan
fuente
3

Esto funciona para mí. No estoy seguro de por qué todos buscaban un Mapa, Lista> Todo lo que necesitaba era un simple nombre de valor Mapa.

Para simplificar las cosas, utilicé la compilación en URI.getQuery ();

public static Map<String, String> getUrlParameters(URI uri)
    throws UnsupportedEncodingException {
    Map<String, String> params = new HashMap<String, String>();
    for (String param : uri.getQuery().split("&")) {
        String pair[] = param.split("=");
        String key = URLDecoder.decode(pair[0], "UTF-8");
        String value = "";
        if (pair.length > 1) {
            value = URLDecoder.decode(pair[1], "UTF-8");
        }
        params.put(new String(key), new String(value));
    }
    return params;
}
Dave
fuente
1
¿Qué tal formularios con selección múltiple? Es perfectamente normal tener claves repetidas en cadenas de consulta legítimas (y cuerpos de formulario POST). Hay otros defectos y esquinas no cubiertas; Muchos de ellos han sido mencionados en comentarios sobre otros enfoques. Me abstendré de que el formulario los señale por temor a que lo arregles en lugar de usar una biblioteca de calidad, según mi comentario en la pregunta;)
Será
2

El multimapa de guayaba es más adecuado para esto. Aquí hay una versión corta y limpia:

Multimap<String, String> getUrlParameters(String url) {
        try {
            Multimap<String, String> ret = ArrayListMultimap.create();
            for (NameValuePair param : URLEncodedUtils.parse(new URI(url), "UTF-8")) {
                ret.put(param.getName(), param.getValue());
            }
            return ret;
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
pathikrit
fuente
1

Originalmente respondido aquí

En Android, hay una clase Uri en el paquete android.net . Tenga en cuenta que Uri es parte de android.net, mientras que URI es parte de java.net.

La clase Uri tiene muchas funciones para extraer pares de clave-valor de consulta. ingrese la descripción de la imagen aquí

La siguiente función devuelve pares clave-valor en forma de HashMap.

En Java:

Map<String, String> getQueryKeyValueMap(Uri uri){
    HashMap<String, String> keyValueMap = new HashMap();
    String key;
    String value;

    Set<String> keyNamesList = uri.getQueryParameterNames();
    Iterator iterator = keyNamesList.iterator();

    while (iterator.hasNext()){
        key = (String) iterator.next();
        value = uri.getQueryParameter(key);
        keyValueMap.put(key, value);
    }
    return keyValueMap;
}

En Kotlin:

fun getQueryKeyValueMap(uri: Uri): HashMap<String, String> {
        val keyValueMap = HashMap<String, String>()
        var key: String
        var value: String

        val keyNamesList = uri.queryParameterNames
        val iterator = keyNamesList.iterator()

        while (iterator.hasNext()) {
            key = iterator.next() as String
            value = uri.getQueryParameter(key) as String
            keyValueMap.put(key, value)
        }
        return keyValueMap
    }
Ramakrishna Joshi
fuente
0

No creo que haya uno en JRE. Puede encontrar funciones similares en otros paquetes como Apache HttpClient. Si no utiliza ningún otro paquete, solo tiene que escribir el suyo. No es tan dificil. Esto es lo que uso

public class QueryString {

 private Map<String, List<String>> parameters;

 public QueryString(String qs) {
  parameters = new TreeMap<String, List<String>>();

  // Parse query string
     String pairs[] = qs.split("&");
     for (String pair : pairs) {
            String name;
            String value;
            int pos = pair.indexOf('=');
            // for "n=", the value is "", for "n", the value is null
         if (pos == -1) {
          name = pair;
          value = null;
         } else {
       try {
        name = URLDecoder.decode(pair.substring(0, pos), "UTF-8");
              value = URLDecoder.decode(pair.substring(pos+1, pair.length()), "UTF-8");            
       } catch (UnsupportedEncodingException e) {
        // Not really possible, throw unchecked
           throw new IllegalStateException("No UTF-8");
       }
         }
         List<String> list = parameters.get(name);
         if (list == null) {
          list = new ArrayList<String>();
          parameters.put(name, list);
         }
         list.add(value);
     }
 }

 public String getParameter(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  if (values.size() == 0)
   return "";

  return values.get(0);
 }

 public String[] getParameterValues(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  return (String[])values.toArray(new String[values.size()]);
 }

 public Enumeration<String> getParameterNames() {  
  return Collections.enumeration(parameters.keySet()); 
 }

 public Map<String, String[]> getParameterMap() {
  Map<String, String[]> map = new TreeMap<String, String[]>();
  for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
   List<String> list = entry.getValue();
   String[] values;
   if (list == null)
    values = null;
   else
    values = (String[]) list.toArray(new String[list.size()]);
   map.put(entry.getKey(), values);
  }
  return map;
 } 
}
Codificador ZZ
fuente
¿Cuál es el camino con las clases de apache?
Será el
1
Puede usar el método parse (): hc.apache.org/httpcomponents-client/httpclient/apidocs/org/…
ZZ Coder
3
Ponga el enlace de apache commons en su propia respuesta para que pueda votarlo.
itsadok el
0

Basado en la respuesta de BalusC, escribí un código Java de ejemplo:

    if (queryString != null)
    {
        final String[] arrParameters = queryString.split("&");
        for (final String tempParameterString : arrParameters)
        {
            final String[] arrTempParameter = tempParameterString.split("=");
            if (arrTempParameter.length >= 2)
            {
                final String parameterKey = arrTempParameter[0];
                final String parameterValue = arrTempParameter[1];
                //do something with the parameters
            }
        }
    }
Andreas
fuente
0
public static Map <String, String> parseQueryString (final URL url)
        throws UnsupportedEncodingException
{
    final Map <String, String> qps = new TreeMap <String, String> ();
    final StringTokenizer pairs = new StringTokenizer (url.getQuery (), "&");
    while (pairs.hasMoreTokens ())
    {
        final String pair = pairs.nextToken ();
        final StringTokenizer parts = new StringTokenizer (pair, "=");
        final String name = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        final String value = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        qps.put (name, value);
    }
    return qps;
}
wafna
fuente
0

usando guayaba:

Multimap<String,String> parseQueryString(String queryString, String encoding) {
    LinkedListMultimap<String, String> result = LinkedListMultimap.create();

    for(String entry : Splitter.on("&").omitEmptyStrings().split(queryString)) {
        String pair [] = entry.split("=", 2);
        try {
            result.put(URLDecoder.decode(pair[0], encoding), pair.length == 2 ? URLDecoder.decode(pair[1], encoding) : null);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    return result;
}
Tyson
fuente
0

Respondiendo aquí porque este es un hilo popular. Esta es una solución limpia en Kotlin que utiliza la UrlQuerySanitizerAPI recomendada . Ver la documentación oficial . He agregado un generador de cadenas para concatenar y mostrar los parámetros.

    var myURL: String? = null
    // if the url is sent from a different activity where you set it to a value
    if (intent.hasExtra("my_value")) {
        myURL = intent.extras.getString("my_value")
    } else {
        myURL = intent.dataString
    }

    val sanitizer = UrlQuerySanitizer(myURL)
    // We don't want to manually define every expected query *key*, so we set this to true
    sanitizer.allowUnregisteredParamaters = true
    val parameterNamesToValues: List<UrlQuerySanitizer.ParameterValuePair> = sanitizer.parameterList
    val parameterIterator: Iterator<UrlQuerySanitizer.ParameterValuePair> = parameterNamesToValues.iterator()

    // Helper simply so we can display all values on screen
    val stringBuilder = StringBuilder()

    while (parameterIterator.hasNext()) {
        val parameterValuePair: UrlQuerySanitizer.ParameterValuePair = parameterIterator.next()
        val parameterName: String = parameterValuePair.mParameter
        val parameterValue: String = parameterValuePair.mValue

        // Append string to display all key value pairs
        stringBuilder.append("Key: $parameterName\nValue: $parameterValue\n\n")
    }

    // Set a textView's text to display the string
    val paramListString = stringBuilder.toString()
    val textView: TextView = findViewById(R.id.activity_title) as TextView
    textView.text = "Paramlist is \n\n$paramListString"

    // to check if the url has specific keys
    if (sanitizer.hasParameter("type")) {
        val type = sanitizer.getValue("type")
        println("sanitizer has type param $type")
    }
jungledev
fuente
-2

este método toma la uri y el mapa de retorno del nombre y valor nominal

  public static Map<String, String> getQueryMap(String uri) {

    String queryParms[] = uri.split("\\?");

    Map<String, String> map = new HashMap<>();// 

    if (queryParms == null || queryParms.length == 0) return map;

    String[] params = queryParms[1].split("&");
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }
    return map;
}
FAHAD HAMMAD ALOTAIBI
fuente
1
Según mi discurso anterior, esto se puede hacer trivialmente para que se bloquee. No te molestes en arreglarlo, solo usa una biblioteca de utilidad profesional.
Se
-3

Dices "Java" pero "no Java EE". ¿Quiere decir que está utilizando JSP y / o servlets pero no una pila Java EE completa? Si ese es el caso, entonces aún debería tener request.getParameter () disponible para usted.

Si quiere decir que está escribiendo Java pero no está escribiendo JSP ni servlets, o que solo está utilizando Java como punto de referencia, pero está en otra plataforma que no tiene un análisis de parámetros incorporado ... Wow , eso suena como una pregunta poco probable, pero si es así, el principio sería:

xparm=0
word=""
loop
  get next char
  if no char
    exit loop
  if char=='='
    param_name[xparm]=word
    word=""
  else if char=='&'
    param_value[xparm]=word
    word=""
    xparm=xparm+1
  else if char=='%'
    read next two chars
    word=word+interpret the chars as hex digits to make a byte
  else
    word=word+char

(Podría escribir código Java, pero eso no tendría sentido, porque si tiene Java disponible, puede usar request.getParameters).

Arrendajo
fuente
cuidado con la codificación de caracteres al decodificar url los dígitos hexadecimales.
Mr. Shiny and New 安 宇
Es Android, por lo tanto, Java pero no J2EE.
Andrzej Doyle el
Olvidé mencionar: También debe verificar "+", que debe traducirse a un espacio. Los espacios incrustados son ilegales en una cadena de consulta.
Jay