Android'de sorgu dizelerini ayrıştırma


271

Java EE'de ServletRequest.getParameterValues ​​() vardır .

EE olmayan platformlarda URL.getQuery () yalnızca bir dize döndürür.

Java EE'de değilken bir URL'deki sorgu dizesini doğru şekilde ayrıştırmanın normal yolu nedir ?


< rant >

Kendi ayrıştırıcıyı denemek ve yapmak için cevaplarda popüler. Bu çok ilginç ve heyecan verici bir mikro kodlama projesi, ancak bunun iyi bir fikir olduğunu söyleyemem :(

Aşağıdaki kod parçacıkları genellikle kusurlu veya bozuktur, btw. Onları kırmak okuyucu için ilginç bir alıştırmadır. Ve onları kullanan web sitelerine saldıran hackerlara .

Sorgu dizelerini ayrıştırmak iyi tanımlanmış bir sorundur, ancak spesifikasyonu okumak ve nüansları anlamak önemsiz değildir. Bazı platform kütüphanesi kodlayıcısının zor işi yapmasına ve düzeltmeyi sizin için yapmasına izin vermek çok daha iyidir!

< / rant >


Örnek bir URL gönderebilir misiniz, ne alıyorsunuz getQuery()ve çıktı olarak ne almak istiyorsunuz?
Thomas Owens

1
Bunu bir sunucu uygulamasından veya bir JSP sayfasından yapmak istiyor musunuz? Cevap vermeden önce biraz açıklığa ihtiyacım var.
ChadNC

1
POST parametrelerini de ayrıştırmanız mı gerekiyor?
Thilo

2
J2EE'de (ya da benim gibi OSGi aracılığıyla seçilen EE paketleri eklenmiş SE'de) olsanız bile, bu soru mantıklı olabilir. Benim durumumda, sorgu dizeleri / url kodlu POST gövdeleri, sistemin kasıtlı olarak agnostik olan bir kısmı tarafından işlenir ServletRequest.
Hanno Fietz

61
<Rant /> için seçildi!
Nowaker

Yanıtlar:


65

Android M'den beri işler daha karmaşık hale geldi. Cevabı android.net.URI .getQueryParameter () JellyBean önce boşluk kırar bir hata var. Apache URLEncodedUtils.parse () çalıştı, ancak L kaldırıldı ve M uzaklaştırıldı .

Şimdi en iyi cevap UrlQuerySanitizer . Bu, API düzey 1'den beri varlığını sürdürüyor ve hala var. Ayrıca, özel karakterleri veya tekrarlanan değerleri nasıl ele aldığınız gibi zor konular hakkında düşünmenizi sağlar.

En basit kod

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

Varsayılan ayrıştırma davranışından memnunsanız şunları yapabilirsiniz:

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

ancak varsayılan ayrıştırma davranışının ne olduğunu anladığınızdan emin olmalısınız, çünkü istediğiniz şey olmayabilir.


4
URLQuerySanitizer.getAllButNullLegal (), UrlQuerySanitizer öğesini değil, UrlQuerySanitizer.ValueSanitizer öğesini döndürür.
Peter Zhao

31
Nedense yukarıdaki benim için işe yaramadı, ben biraz değiştirmek zorunda - daha da kolaylaştırır:UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL); String value = sanitizer.getValue("parameter");
SeBsZ

3
Çalışmıyor. UrlQuerySanitizer sdk-23'te tek bir yöntem varsanitize()
Ninja

Bu, özel karakterlerin ve emojilerin kodunu çözecektir _. Stackoverflow.com/a/35638979/1155282
Irshu

Bunun bir yay çerçevesi eşdeğeri kütüphanesi var mı?
iamjoshua

202

Android'de:

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");

20
bunun URI sınıfını değil Uri sınıfını kullandığını unutmayın (Uri android.net'in bir parçası iken URI java.net'in bir parçasıdır)
Marius

5
Ayrıca, Ice Cream Sandwich'den önce, bu değerlerde + karakterleri bir boşluk karakterine ayrıştırmadığını unutmayın.
rpetrich

@rpetrich aslında dokümanlar, Ice Cream Sandwich de dahil olmak üzere, Jelly Bean'den önce hata olduğunu söylüyor. Ref
Big McLargeHuge

64

9
Bu, yalnızca Android'de değil, apache http istemci kitaplığında da bulunur. Btw, apache bağlantısı değiştirildi. En son: hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…
Cristian Vrabie

9
Can sıkıcı URLEncodedUtils.parse()bir Listşekilde daha sonra belirli bir anahtarın değerini bulmak için döngü yapmanız gereken bir döndürür . MapBalusC'nin cevabına benzer bir şekilde dönerse çok daha güzel olurdu .
Asaph

1
@Hanno Fietz, bu alternatiflere güvendiğinizi mi söylüyorsunuz ? Buggy olduklarını biliyorum. Gördüğüm hatalara işaret etmek, insanları gözden kaçırdığım hataları aramak yerine, yalnızca 'sabit' sürümleri benimsemeye teşvik edecektir.
Will

1
@Will - şey, hiçbir zaman sadece herhangi bir web sitesinden aldığım kopyala ve yapıştır pasajlarına güvenmem ve hiç kimsenin yapmaması gerekir. Ancak burada, bu snippet'ler oldukça iyi incelenir ve yorumlanır ve areaslında gerçekten yararlıdır. Kodda neyin yanlış olabileceğine dair bazı öneriler görmek , kendim için düşünmede zaten çok yardımcı oldu. Ve unutmayın ki, "kendininkini yuvarla daha iyi" demek istemedim, aksine kendi kodumda bilinçli bir karar için iyi bir malzemeye sahip olmak harika.
Hanno Fietz

8
Ayrıştırma, bir konumsal sıralaması korumak ve daha kolay yinelenen girişleri izin böylece bir liste döndürür hayal.
dhaag23

26

İşte BalusC'nin cevabı , ancak sonuçları derler ve döndürür:

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

1
JVM Not: Scala'da bunun için Java Koleksiyonlarını kullanarak eşdeğer bir form uyguladım; İşte github özü: gist.github.com/3504765
Jay Taylor

2
I değişen önermek String pair[] = param.split("=");içine String pair[] = param.split("=", 2);sadece ilk geçtiği anahtar = değer çifti bölmek. Ben kodlanmamış değeri eşit işaretleri olmasına izin olduğuna inanıyorum.
Dennie

22

Sınıf yolunuzda iskele (sunucu veya istemci) kütüphaneleri varsa, iskele util sınıflarını kullanabilirsiniz (bkz. Javadoc ), örneğin:

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");

13

Spring 3.1 veya üstünü kullanıyorsanız (yikes, desteğin daha da geri gitmesini umuyorduysanız), UriComponentsve öğelerini kullanabilirsiniz UriComponentsBuilder:

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

components.getQueryParams() döndürür MultiValueMap<String, String>

İşte biraz daha dokümantasyon .


Bu aradığım bir şey. Benim sorum uri'yi nasıl alabilirim? Ben çok değiştiremiyorum kod bakım ile sıkışmış ve biz HttpServlet kullanmıyoruz. Bunun yerine yalnızca ek açıklamaları ve Bahar'ı kullanma (@Get, @Produces (mediaType) ve @Path ("/ dataAsJSON / datafield / {datafield})) Bu örnek
Nelda.techspiress

5

Bir sunucu uygulaması veya JSP sayfası için request.getParameter ("paramname") öğesini kullanarak querystring anahtar / değer çiftlerini alabilirsiniz

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

Bunu yapmanın başka yolları da var ama bunu oluşturduğum tüm sunucu uygulamaları ve jsp sayfalarında yapıyorum.


3
HttpServletRequest, sahip olmadığı J2EE'nin bir parçasıdır. Ayrıca getParamter () kullanmak gerçekten ayrıştırmak değildir.
Bay Parlak ve Yeni 宇 宇

3
Lütfen sorusunu açıklığa kavuşturmak istediğim yorumu okumak için zaman ayırın. Bu yanıt, "Bunu Android'de yapmaya çalışıyorum, ancak tüm platformlardaki tüm yanıtlar, işaretçiler verebilecek yararlı yanıtlar olacaktır (ayrıca bununla karşılaşabilecek diğer kişilere de). soru) öyleyse geri durma! " Bu yoruma dayanarak sorusunu cevapladım. Eklemek için yararlı bir şeyiniz yoksa hiçbir şey eklemeyin
ChadNC

1
Çok üzülme. "Bu soruya cevap vermiyor" IMO eklemek için kullanışlıdır.
Bay Parlak ve Yeni 宇 宇

1
Android'in önemi yok ya da değil, soru, URL içeren Dize'nin nasıl ayrıştırılacağı ve URL parametrelerinin nasıl çıkarılacağıdır. Burada taşıdığınız şey Servlet kapsayıcısının sizin için HTTP isteğinden gelen parametreleri ayrıştırdığı Servlet API'sının bir parçasıdır. Bu önemsizdir, çünkü soru Servlet kapsayıcısının içinde değil, HTTP isteğini değil URL'yi içeren Dizeyi ayrıştırmakla ilgilidir.
mvmn

5

Android'de, ben @diyism cevabı kullanarak çalıştı ancak örneğin @rpetrich tarafından gündeme boşluk karakteri sorunu karşılaştı: Ben bir form doldurup nerede username = "us+us"ve password = "pw pw"benzeri görünüm için bir URL dizesi neden:

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

Bununla birlikte, @diyism kodu döner "us+us"ve "pw+pw"yani boşluk karakterini algılamaz. URL %20boşluk karakteriyle yeniden yazıldıysa tanımlanır:

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

Bu, aşağıdaki düzeltmeye yol açar:

Uri uri = Uri.parse(url_string.replace("+", "%20"));
uri.getQueryParameter("para1");

replace(" ", "%20")bu yanlış geliyor. Ama benim için hile yaptı: D
Brirtiņš Briedis

Doğru sözdizimi "some string" olmalıdır .replaceAll ("[+]", "% 20");
RRTW

4

Ne kadar affetmek istediğinize bağlı olarak, sorgu dizesini ayrıştırmak göründüğünden biraz daha karmaşıktır.

İlk olarak, sorgu dizesi ascii bayttır. Bu baytları teker teker okursunuz ve karakterlere dönüştürüyorsunuz. Karakter ise? veya & sonra bir parametre adının başlangıcını işaret eder. Karakter = ise, bir parametre değerinin başlangıcını işaret eder. Karakter% ise, kodlanmış bir baytın başlangıcını işaret eder. İşte burada zorlaşıyor.

Bir% char içinde okuduğunuzda, sonraki iki baytı okumanız ve onaltılık basamak olarak yorumlamanız gerekir. Bu, sonraki iki baytın 0-9, af veya AF olacağı anlamına gelir. Bayt değerinizi elde etmek için bu iki onaltılık haneyi birbirine yapıştırın. Ancak unutmayın, baytlar karakter değildir . Karakterleri kodlamak için hangi kodlamanın kullanıldığını bilmelisiniz. É karakteri UTF-8'de ISO-8859-1'de olduğu gibi kodlamaz. Genel olarak, belirli bir karakter seti için hangi kodlamanın kullanıldığını bilmek imkansızdır. Her zaman UTF-8 kullanıyorum çünkü web sitem her zaman UTF-8 kullanarak her şeye hizmet verecek şekilde yapılandırıldı, ancak pratikte emin olamıyorsunuz. Bazı kullanıcı aracıları size istekte karakter kodlamasını söyleyecektir; tam bir HTTP isteğiniz varsa bunu okumaya çalışabilirsiniz. Yalnız bir url'niz varsa, iyi şanslar.

Her neyse, UTF-8 veya başka bir çok baytlık karakter kodlaması kullandığınızı varsayarsak, şimdi bir kodlanmış bayt kodunu çözdüğünüze göre, bir sonraki baytı yakalayana kadar bir kenara koymanız gerekir. Bir arada kodlanmış baytlara ihtiyacınız vardır, çünkü bir seferde bir bayt düzgün şekilde çözemezsiniz. Birlikte olan tüm baytları bir kenara koyun ve karakterinizi yeniden yapılandırmak için hepsini bir kerede kodunu çözün.

Ayrıca, esnek olmak ve url'leri yöneten kullanıcı aracılarını hesaba katmak istiyorsanız daha eğlenceli olur. Örneğin, bazı web posta istemcileri bir şeyleri iki kez kodlar. Veya? & = Karakterleri ikiye katlayın (örneğin:) http://yoursite.com/blah??p1==v1&&p2==v2. Bununla zarif bir şekilde uğraşmak istiyorsanız, ayrıştırıcıya daha fazla mantık eklemeniz gerekir.


Bu sorgu dizesi parametre değerlerini ayrıştırma veya alma
açıklamıyor

Doğru, ama biraz hantal. Bunun için zaten URLDecoder'ımız var.
BalusC

2
@ChadNC: üçüncü cümle size nasıl ayrıştırılacağını söyler: her seferinde bir baytta okuma ve karakterlere dönüştürme. Dördüncü cümle sizi özel karakterlere karşı uyarır. Vb Belki de cevabı okumadınız?
Bay Parlak ve Yeni 宇 宇

@BalusC: URLDecoder çalışır, ancak ne tür bir URL'yi kabul ettiğiniz konusunda daha yumuşak olmaya çalışıyorsanız bazı hata modları vardır.
Bay Parlak ve Yeni 宇 宇

1
@ Mr.ShinyAndNew ile ayrıştırma sorgu parametresi kolay değil. FIQL destekliyorum ve bu eşek gerçek bir ağrı haline gelir. Örn: siteniz.com/blah??p1==v1&&p2==v2,p2==v3;p2==v4
rafa.ferreira

4

Android'de aşağıdaki kod kadar basit:

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

Ayrıca, beklenen her sorgu anahtarı kullanımını kaydetmek istemiyorsanız:

sanitzer.setAllowUnregisteredParamaters(true)

Aramadan önce:

sanitzer.parseUrl(yourUrl)

4

Bunu başarmak için yöntemler var:

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) ve bunu yapmanın en kolay yolu Uri sınıfını kullanma :

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

ve bu iki yöntemden birinin nasıl kullanılacağına dair bir örnektir:

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

tagValue değeri 800


3

Android'de, ağır kaldırma yapmak için android.net.Uri sınıfının Uri.parse statik yöntemini kullanabilirsiniz . URI'ler ve Amaçlar ile bir şey yapıyorsanız, yine de kullanmak istersiniz.


3

Sadece referans için, ben (URLEncodedUtils ve bir Harita döndürme dayalı) ile sonuçlanan budur.

Özellikleri:

  • URL'nin sorgu dizesi kısmını kabul eder (kullanabilirsiniz request.getQueryString())
  • boş bir sorgu dizesi boş bir Map
  • değeri olmayan bir parametre (? testi) boş bir değerle eşlenir List<String>

Kod:

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

Bir uyumluluk yardımcısı (değerler, ServletRequest.getParameterMap () gibi bir String dizisinde saklanır ):

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

3

Bu benim için çalışıyor .. Neden her bir Harita, Liste> Tek ihtiyacım olan basit bir isim değeri Harita oldu sonra emin değilim.

İşleri basit tutmak için 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;
}

1
çoktan seçmeli formlara ne dersiniz? Meşru sorgu dizelerinde (ve POST form gövdelerinde) anahtarların tekrarlanması çok normaldir. Kapsanmayan başka kusurlar ve köşe vakaları var; birçoğu diğer yaklaşımlarla ilgili yorumlarda belirtilmiştir. Bunu düzeltmek korkusuyla bunları işaret yerine benim gereğince, kaliteli bir kitaplığı kullanarak formu kaçınmaları gerekir rant söz konusu;)
Will

2

Guava'nın Multimap'ı bunun için daha uygundur. İşte kısa ve temiz bir versiyon:

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


1

Başlangıçta cevaplandı burada

Android'de android.net paketinde Uri sınıfı var . Uri'nin android.net'in bir parçası olduğunu, URI'nin ise java.net'in bir parçası olduğunu unutmayın.

Uri sınıfı, sorgu anahtar / değer çiftlerini ayıklamak için birçok işleve sahiptir. resim açıklamasını buraya girin

Aşağıdaki işlev, anahtar / değer çiftlerini HashMap biçiminde döndürür.

Java dilinde:

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

Kotlin'de:

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
    }

0

JRE'de bir tane olduğunu sanmıyorum. Benzer işlevleri Apache HttpClient gibi diğer paketlerde de bulabilirsiniz. Başka paket kullanmıyorsanız, sadece kendi paketinizi yazmanız gerekir. O kadar zor değil. İşte kullandığım,

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

Apache sınıflarının yolu nedir?
Will


3
Oy verebilmem için lütfen apache commons bağlantısını kendi cevabına koyun.
itsadok

0

BalusC'nin cevabına dayanarak, bazı örnek-Java-Code yazdım:

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

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


0

Guava kullanarak:

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

0

Buraya cevap veriyorum çünkü bu popüler bir konu. Bu Kotlin'de önerilen API'yi kullanan temiz bir çözümdür UrlQuerySanitizer. Resmi belgelere bakın . Parametre birleştirmek ve görüntülemek için bir dize oluşturucu ekledim.

    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")
    }

-2

bu yöntem par adının ve par değerinin uri ve dönüş haritasını alır

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

1
Yukarıdaki rant göre, bu önemsizce çökmesine yapılabilir. Düzeltmeyi zahmet etmeyin, bunun yerine profesyonel bir yardımcı program kitaplığı kullanın.
Will

-3

"Java" diyorsunuz, "Java EE değil" diyorsunuz. Yani JSP ve / veya sunucu uygulamaları kullanıyor ancak tam bir Java EE yığını kullanmıyor musunuz? Bu durumda, yine de request.getParameter () kullanabilmelisiniz.

Java yazdığınızı, ancak JSP'leri veya sunucu uygulamalarını yazmıyorsanız veya Java'yı referans noktanız olarak kullandığınızı ancak yerleşik parametre ayrıştırması olmayan başka bir platformda olduğunuzu söylüyorsanız ... , bu sadece beklenmedik bir soru gibi geliyor, ancak öyleyse, ilke:

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

(Java kodunu yazabilirim ama bu anlamsız olurdu, çünkü Java'nız varsa, request.getParameters'ı kullanabilirsiniz.)


onaltılık basamakların url kodunu çözerken karakter kodlamasına dikkat edin.
Bay Parlak ve Yeni 宇 宇

Android, dolayısıyla Java ama J2EE değil.
Andrzej Doyle

Söylemeyi unuttum: Ayrıca bir alana çevrilmesi gereken "+" işaretini de kontrol etmeniz gerekir. Yerleştirilmiş alanlar bir sorgu dizesinde yasa dışıdır.
Jay
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.