Analisando cadeias de consulta no Android

271

O Java EE possui ServletRequest.getParameterValues ​​() .

Em plataformas não EE, URL.getQuery () simplesmente retorna uma sequência.

Qual é a maneira normal de analisar adequadamente a sequência de consultas em uma URL quando não está no Java EE?


< discurso retórico >

É popular nas respostas para tentar criar seu próprio analisador. Este é um projeto de micro-codificação muito interessante e emocionante, mas não posso dizer que é uma boa idéia :(

Os trechos de código abaixo geralmente são falhos ou quebrados, btw. Quebrá-los é um exercício interessante para o leitor. E para os hackers que atacam os sites que os usam .

A análise de cadeias de consulta é um problema bem definido, mas a leitura das especificações e a compreensão das nuances não são triviais. É muito melhor deixar que algum codificador de biblioteca de plataforma faça o trabalho duro e faça a correção para você!

< / rant >

Vai
fonte
Você poderia postar um URL de amostra, do que está obtendo getQuery()e do que deseja obter como saída?
9789 Thomas
1
Você deseja fazer isso em um servlet ou em uma página JSP? Preciso de alguns esclarecimentos antes de responder.
ChadNC 03/11/2009
1
Você também precisa analisar os parâmetros do POST?
Thilo #
2
Mesmo se você estiver no J2EE (ou no SE com pacotes EE selecionados adicionados via OSGi, como eu), essa pergunta poderá fazer sentido. No meu caso, as cadeias de consulta / corpos POST codificados por URL são processados ​​por uma parte do sistema que é intencionalmente independente de coisas do tipo ServletRequest.
Hanno Fietz
61
Voto por favor para <rant />!
Nowaker

Respostas:

65

Desde o Android M, as coisas ficaram mais complicadas. A resposta de android.net.URI .getQueryParameter () possui um erro que quebra os espaços antes do JellyBean. O Apache URLEncodedUtils.parse () funcionou, mas foi preterido em L e removido em M .

Então a melhor resposta agora é UrlQuerySanitizer . Isso existe desde o nível 1 da API e ainda existe. Também faz você pensar em questões complicadas, como lidar com caracteres especiais ou valores repetidos.

O código mais simples é

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

Se você estiver satisfeito com o comportamento de análise padrão, poderá:

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

mas certifique-se de entender qual é o comportamento padrão da análise, pois pode não ser o que você deseja.

Nick Fortescue
fonte
4
URLQuerySanitizer.getAllButNullLegal () retorna UrlQuerySanitizer.ValueSanitizer, não UrlQuerySanitizer.
Peter Zhao
31
Por alguma razão o acima não funcionou para mim, eu tive que modificá-lo apenas ligeiramente - o que torna ainda mais fácil:UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL); String value = sanitizer.getValue("parameter");
SeBsZ
3
Não funciona. UrlQuerySanitizer no sdk-23 tem apenas um método #sanitize()
ninja
Isso decodificará caracteres especiais e emoji para _. Eu tive que ir com stackoverflow.com/a/35638979/1155282
Irshu
Existe uma biblioteca equivalente ao framework spring?
Iamjoshua 29/11/19
202

No Android:

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");
diyism
fonte
20
nota que este usa a classe Uri e não a classe URI (Uri é parte de android.net, enquanto URI é parte de java.net)
Marius
5
Observe também que, antes do Ice Cream Sandwich, isso falha ao analisar caracteres + em valores para um caractere de espaço.
Rpetrich 7/12/12
@rpetrich, na verdade, os médicos dizem que o bug é anterior ao Jelly Bean, incluindo Ice Cream Sandwich. ref
Big McLargeHuge 18/06/19
64

No Android, as bibliotecas Apache fornecem um analisador de consultas:

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

Vai
fonte
9
Está disponível na biblioteca do cliente http apache, não apenas no Android. Btw, o link para o apache foi alterado. O mais recente é: hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…
Cristian Vrabie
9
Irritantemente URLEncodedUtils.parse()retorna um Listque você precisaria percorrer para encontrar o valor de uma chave específica. Seria muito melhor se isso retornasse algo Mapparecido na resposta de BalusC.
Asaph
1
@ Hanno Fietz, quer dizer que confia nessas alternativas? Eu sei que eles são buggy. Eu sei que apontar os bugs que vejo apenas incentivará as pessoas a adotarem versões 'fixas', em vez de procurarem os bugs que eu ignorei.
Will
1
@ Will - bem, eu nunca confiaria apenas trechos de copiar e colar que obtive de qualquer site, e ninguém deveria. Mas aqui, esses trechos são bastante bem revisados ​​e comentados e, portanto, arerealmente úteis. Simplesmente ver algumas sugestões sobre o que pode estar errado com o código já é uma grande ajuda para pensar por mim mesmo. E lembre-se, eu não quis dizer "rolar o seu próprio é melhor", mas sim que é ótimo ter um bom material para uma decisão informada no meu próprio código.
Hanno Fietz 23/05
8
Eu imagino que a análise retorna uma lista para manter a ordem de posicionamento e permitir mais facilmente entradas duplicadas.
dhaag23
26

Aqui está a resposta do BalusC , mas ele compila e retorna 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
fonte
1
Nota da JVM: Eu implementei uma forma equivalente disso no Scala usando Java Collections; aqui é a essência github: gist.github.com/3504765
Jay Taylor
2
Sugiro mudando String pair[] = param.split("=");para String pair[] = param.split("=", 2);dividir a chave = valor par apenas na primeira ocorrência. Eu acredito que é permitido ter sinais de igualdade não codificados no valor.
Dennie
22

Se você possui bibliotecas jetty (servidor ou cliente) em seu caminho de classe, pode usar as classes utilitárias jetty (consulte javadoc ), por exemplo:

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
fonte
13

Se você estiver usando o Spring 3.1 ou superior (caramba, esperava que o suporte voltasse mais), você pode usar o UriComponentse UriComponentsBuilder:

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

components.getQueryParams() retorna um MultiValueMap<String, String>

Aqui está mais uma documentação .

Nick Spacek
fonte
Isso é algo que estou procurando. Minha pergunta é como faço para obter a uri? Estou preso com a manutenção do código que não posso mudar muito e não estamos usando o HttpServlet. Em vez disso, basta usar anotações e Spring (@Get, @Produces (mediaType) e @Path ("/ dataAsJSON / datafield / {datafield})). Só preciso saber como obter a string de consulta para que eu possa analisá-la, como é mostrado em este exemplo.
Nelda.techspiress
5

Para um servlet ou uma página JSP, é possível obter pares de chave / valor da string de consulta usando request.getParameter ("paramname")

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

Existem outras maneiras de fazer isso, mas é assim que faço em todos os servlets e páginas jsp que eu crio.

ChadNC
fonte
3
HttpServletRequest faz parte do J2EE que ele não possui. Também usar getParamter () não é realmente uma análise.
Mr. Shiny and New #
3
Por favor, reserve um tempo para ler o comentário no qual pedi esclarecimentos sobre sua pergunta. Esta resposta é uma resposta à sua resposta a esse comentário no qual ele declarou: "Estou tentando fazer isso no Android, mas todas as respostas em todas as plataformas seriam respostas úteis que podem dar dicas (também para outras pessoas que possam se deparar com isso). pergunta), então não se contenha! " Eu respondi a sua pergunta com base nesse comentário. Se você não tem nada de útil a acrescentar, não acrescentam nada
ChadNC
1
Não fique muito chateado. "Isso não responde à pergunta" é útil para adicionar, IMO.
Mr. Shiny and New #
1
Não importa o Android ou não, a questão é como analisar String contendo URL e obter parâmetros de URL. O que você está portando aqui faz parte da API do Servlet, onde o contêiner do Servlet analisa os parâmetros recebidos da solicitação HTTP para você. É irrelevante, porque a pergunta é sobre a análise de String que contém URL, não solicitação HTTP e não dentro do contêiner Servlet.
Mvmn
5

No Android, eu tentei usar resposta @diyism mas encontrou o problema caractere de espaço levantada por @rpetrich, por exemplo: eu preencher um formulário onde username = "us+us"e password = "pw pw"causando uma seqüência de URL para se parecer com:

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

No entanto, o código @diyism retorna "us+us"e "pw+pw", ou seja, ele não detecta o caractere de espaço. Se o URL foi reescrito com %20o caractere de espaço, é identificado:

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

Isso leva à seguinte correção:

Uri uri = Uri.parse(url_string.replace("+", "%20"));
uri.getQueryParameter("para1");
Stephen Quan
fonte
replace(" ", "%20")isso parece errado. Mas fiz o truque para mim: D
Mārtiņš Briedis 10/10/2013
A sintaxe correta deve ser "alguma string" .replaceAll ("[+]", "% 20");
RRTW
4

A análise da string de consulta é um pouco mais complicada do que parece, dependendo de como você deseja perdoar.

Primeiro, a cadeia de caracteres da consulta é bytes ascii. Você lê esses bytes um de cada vez e os converte em caracteres. Se o personagem é? ou & então sinaliza o início do nome de um parâmetro. Se o caractere for =, ele sinaliza o início de um valor de parâmetro. Se o caractere for%, ele sinaliza o início de um byte codificado. Aqui é onde fica complicado.

Quando você lê um% char, precisa ler os próximos dois bytes e interpretá-los como dígitos hexadecimais. Isso significa que os próximos dois bytes serão 0-9, af ou AF. Cole esses dois dígitos hexadecimais para obter o valor em bytes. Mas lembre-se, bytes não são caracteres . Você precisa saber qual codificação foi usada para codificar os caracteres. O caractere é não codifica o mesmo em UTF-8 como em ISO-8859-1. Em geral, é impossível saber qual codificação foi usada para um determinado conjunto de caracteres. Eu sempre uso UTF-8 porque meu site está configurado para sempre servir tudo usando UTF-8, mas na prática você não pode ter certeza. Alguns user-agents dirão a codificação de caracteres na solicitação; você pode tentar ler isso se tiver uma solicitação HTTP completa. Se você apenas tem um URL isolado, boa sorte.

De qualquer forma, supondo que você esteja usando UTF-8 ou alguma outra codificação de caracteres de vários bytes, agora que você decodificou um byte codificado, você deve separá-lo até capturar o próximo byte. Você precisa de todos os bytes codificados que estão juntos porque não é possível decodificar por URL um byte por vez. Separe todos os bytes que estão juntos e decodifique-os todos de uma vez para reconstruir seu personagem.

Além disso, fica mais divertido se você quiser ser indulgente e prestar contas de agentes de usuários que alteram URLs. Por exemplo, alguns clientes de webmail codificam duas vezes as coisas. Ou dobre os caracteres? & = (Por exemplo:) http://yoursite.com/blah??p1==v1&&p2==v2. Se você quiser tentar lidar com isso com delicadeza, precisará adicionar mais lógica ao seu analisador.

Sr. Brilhante e Novo 安 宇
fonte
Isso não explica como analisar ou recuperar querystring valores de parâmetros
ChadNC
Certo, mas um pouco complicado. Para isso, já temos o URLDecoder.
BalusC
2
@ChadNC: a terceira frase explica como analisar: leia um byte de cada vez e converta em caracteres. A quarta frase avisa sobre caracteres especiais. Etc. Talvez você não tenha lido a resposta?
Mr. Shiny and New #
@BalusC: URLDecoder funciona, mas possui alguns modos de falha se você estiver tentando ser mais tolerante com o tipo de URL que aceita.
Mr. Shiny and New #
1
Concordo com o parâmetro de consulta de análise @ Mr.ShinyAndNew não é fácil. Estou apoiando o FIQL e isso se torna um verdadeiro problema. Por exemplo: yoursite.com/blah??p1==v1&&p2==v2,p2==v3;p2==v4
rafa.ferreira
4

No Android, é simples como o código abaixo:

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

Além disso, se você não deseja registrar cada chave de consulta esperada, use:

sanitzer.setAllowUnregisteredParamaters(true)

Antes de ligar:

sanitzer.parseUrl(yourUrl)
Kevin Crain
fonte
4

Eu tenho métodos para conseguir isso:

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) e a maneira mais fácil de fazer isso usando a classe 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 "";
}

e este é um exemplo de como usar um dos dois métodos:

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

o valor de tagValue é 800

Jorgesys
fonte
3

No Android, você pode usar o método estático Uri.parse da classe android.net.Uri para fazer o trabalho pesado. Se você estiver fazendo alguma coisa com URIs e Intents, precisará usá-lo de qualquer maneira.

Patrick O'Leary
fonte
3

Apenas para referência, é com isso que eu acabei (baseado em URLEncodedUtils e retornando um mapa).

Recursos:

  • ele aceita a parte da string de consulta do URL (você pode usar request.getQueryString() )
  • uma string de consulta vazia produzirá um vazio Map
  • um parâmetro sem um valor (? test) será mapeado para um vazio 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;
}

Um auxiliar de compatibilidade (os valores são armazenados em uma matriz String, assim como em 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
fonte
3

Isso funciona para mim. Não sei por que todos estavam atrás de um Mapa, Lista> Tudo que eu precisava era de um simples valor de nome Mapa.

Para simplificar, usei a compilação em 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
fonte
1
que tal formulários com seleção múltipla? É perfeitamente normal ter chaves repetidas em seqüências de caracteres legítimas de consulta (e corpos de formulário POST). Existem outros defeitos e cantoneiras não cobertas; muitos deles foram mencionados em comentários sobre outras abordagens. Vou abster-se formulário apontando-os com medo de que você consertá-lo em vez de usar uma biblioteca de qualidade, como por meu discurso na questão;)
Will
2

O Multimap da Guava é mais adequado para isso. Aqui está uma versão curta e limpa:

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
fonte
1

O Apache AXIS2 possui uma implementação independente de QueryStringParser.java. Se você não estiver usando o Axis2, faça o download do código-fonte e do caso de teste aqui -

http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/transport/http/util/QueryStringParser.java

http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/test/org/apache/axis2/transport/http/util/QueryStringParserTest.java

Sripathi Krishnan
fonte
1

Originalmente respondido aqui

No Android, há a classe Uri no pacote android.net . Observe que Uri faz parte do android.net, enquanto o URI faz parte do java.net.

A classe Uri tem muitas funções para extrair pares de valores-chave de consulta. insira a descrição da imagem aqui

A função a seguir retorna pares de valores-chave na forma de HashMap.

Em 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;
}

Em 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
fonte
0

Eu não acho que exista um no JRE. Você pode encontrar funções semelhantes em outros pacotes como o Apache HttpClient. Se você não usa nenhum outro pacote, basta escrever o seu. Não é tão difícil. Aqui está o que eu 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;
 } 
}
ZZ Coder
fonte
Qual é o caminho com as classes apache?
Will
1
Você pode usar o método parse (): hc.apache.org/httpcomponents-client/httpclient/apidocs/org/...
ZZ Coder
3
Coloque o link do apache commons em sua própria resposta para que eu possa votar.
itsadok 5/11/09
0

Com base na resposta do BalusC, escrevi um exemplo de código Java:

    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
fonte
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
fonte
0

usando o Goiaba:

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
fonte
0

Respondendo aqui, porque este é um tópico popular. Esta é uma solução limpa no Kotlin que usa a UrlQuerySanitizerAPI recomendada . Veja a documentação oficial . Eu adicionei um construtor de strings para concatenar e exibir os 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
fonte
-2

esse método pega o uri e retorna o mapa do nome e 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
fonte
1
Conforme meu discurso acima, isso pode ser feito trivialmente para falhar. Não se preocupe em consertar, basta usar uma biblioteca de utilitários profissional.
Will
-3

Você diz "Java" mas "não Java EE". Você quer dizer que você está usando JSP e / ou servlets, mas não uma pilha Java EE completa? Se for esse o caso, você ainda deve ter request.getParameter () disponível para você.

Se você quer dizer que está escrevendo Java, mas não está escrevendo JSPs nem servlets, ou que está apenas usando Java como ponto de referência, mas está em alguma outra plataforma que não possui análise de parâmetro integrada ... Uau , isso soa apenas como uma pergunta improvável, mas, se sim, o princípio seria:

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

(Eu poderia escrever código Java, mas isso não faria sentido, porque se você tiver Java disponível, poderá usar request.getParameters.)

Jay
fonte
atente para a codificação de caracteres ao decodificar por URL os dígitos hexadecimais.
Mr. Shiny and New #
É Android, portanto, Java, mas não J2EE.
Andrzej Doyle
Esqueci de mencionar: você também precisa verificar o "+", que deve ser traduzido para um espaço. Os espaços incorporados são ilegais em uma sequência de consultas.
Jay