Memilah string kueri di Android

271

Java EE memiliki ServletRequest.getParameterValues ​​() .

Pada platform non-EE, URL.getQuery () cukup mengembalikan sebuah string.

Apa cara normal untuk mengurai string kueri dengan benar di URL saat tidak di Java EE?


< kata-kata kasar >

Ini populer di jawaban untuk mencoba dan membuat parser Anda sendiri. Ini adalah proyek pengkodean mikro yang sangat menarik dan mengasyikkan, tetapi saya tidak bisa mengatakan bahwa itu adalah ide yang bagus :(

Cuplikan kode di bawah ini umumnya cacat atau rusak, btw. Melanggar mereka adalah latihan yang menarik bagi pembaca. Dan untuk para peretas menyerang situs-situs yang menggunakannya .

Mengurai string kueri adalah masalah yang didefinisikan dengan baik tetapi membaca spek dan memahami nuansa tidak sepele. Adalah jauh lebih baik untuk membiarkan beberapa pustaka platform library melakukan kerja keras, dan melakukan perbaikan, untuk Anda!

< / kata-kata kasar >

Akan
sumber
Bisakah Anda memposting URL sampel, apa yang Anda dapatkan getQuery(), dan apa yang ingin Anda dapatkan sebagai output?
Thomas Owens
1
Apakah Anda ingin melakukan ini dari servlet atau halaman JSP? Saya perlu klarifikasi sebelum menjawab.
ChadNC
1
Apakah Anda juga perlu mengurai parameter POST?
Thilo
2
Bahkan jika Anda menggunakan J2EE (atau di SE dengan paket EE terpilih ditambahkan melalui OSGi, seperti saya), pertanyaan ini bisa masuk akal. Dalam kasus saya, badan kueri string / POST yang disandikan url diproses oleh bagian dari sistem yang sengaja agnostik untuk hal-hal seperti ServletRequest.
Hanno Fietz
61
Dipilih untuk <rant />!
Sekarang,

Jawaban:

65

Sejak Android M hal menjadi lebih rumit. Jawaban android.net.URI .getQueryParameter () memiliki bug yang memecah spasi sebelum JellyBean. Apache URLEncodedUtils.parse () bekerja, tapi usang dalam L , dan dihapus di M .

Jadi jawaban terbaik sekarang adalah UrlQuerySanitizer . Ini sudah ada sejak API level 1 dan masih ada. Ini juga membuat Anda berpikir tentang masalah rumit seperti bagaimana Anda menangani karakter khusus, atau nilai berulang.

Kode yang paling sederhana adalah

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

Jika Anda senang dengan perilaku parsing default yang dapat Anda lakukan:

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

tetapi Anda harus memastikan bahwa Anda memahami apa perilaku penguraian default, karena itu mungkin bukan yang Anda inginkan.

Nick Fortescue
sumber
4
URLQuerySanitizer.getAllButNullLegal () mengembalikan UrlQuerySanitizer.ValueSanitizer, bukan UrlQuerySanitizer.
Peter Zhao
31
Untuk beberapa alasan di atas tidak bekerja untuk saya, saya harus memodifikasinya hanya sedikit - yang membuatnya lebih mudah:UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL); String value = sanitizer.getValue("parameter");
SeBsZ
3
Tidak bekerja. UrlQuerySanitizer di SDK-23 hanya memiliki satu metodesanitize()
Ninja
Ini akan mendekodekan karakter khusus dan emoji ke _. Saya harus menggunakan stackoverflow.com/a/35638979/1155282
Irshu
Apakah ada pustaka kerangka kerja yang setara dengan ini?
iamjoshua
202

Di Android:

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");
diyism
sumber
20
perhatikan bahwa ini menggunakan kelas Uri dan bukan kelas URI (Uri adalah bagian dari android.net, sedangkan URI adalah bagian dari java.net)
Marius
5
Perhatikan juga bahwa sebelum Ice Cream Sandwich, ini gagal mengurai + karakter dalam nilai ke karakter spasi.
rpetrich
@rpetrich sebenarnya dokumen mengatakan bahwa bug ada sebelum Jelly Bean, termasuk Ice Cream Sandwich. ref
Big McLargeHuge
64

Di Android, pustaka Apache menyediakan parser Kueri:

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

Akan
sumber
9
Ini tersedia di pustaka klien apache http, tidak hanya di Android. Btw, tautan ke apache diubah. Terbaru adalah: hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…
Cristian Vrabie
9
Mengganggu URLEncodedUtils.parse()mengembalikan Listbahwa Anda kemudian harus mengulang untuk menemukan nilai untuk kunci tertentu. Akan jauh lebih baik jika dikembalikan Mapseperti pada jawaban BalusC.
Asaf
1
@Hanno Fietz Anda maksud Anda percaya alternatif ini? Saya tahu mereka buggy. Saya tahu menunjukkan bug yang saya lihat hanya akan mendorong orang untuk mengadopsi versi 'diperbaiki', daripada mencari bug yang saya abaikan.
Akan
1
@Will - well, saya tidak akan pernah hanya mempercayai cuplikan salin dan rekat yang saya dapatkan dari situs web mana pun, dan tidak ada yang seharusnya. Tapi di sini, potongan-potongan ini ditinjau dan dikomentari dengan baik dan dengan demikian aresangat membantu, sebenarnya. Cukup melihat beberapa saran tentang apa yang mungkin salah dengan kode sudah sangat membantu dalam berpikir untuk diri saya sendiri. Dan ingatlah, saya tidak bermaksud mengatakan "roll your own is better", tetapi lebih baik memiliki materi yang bagus untuk keputusan berdasarkan informasi dalam kode saya sendiri.
Hanno Fietz
8
Saya membayangkan parse mengembalikan daftar sehingga mempertahankan pemesanan posisi dan lebih mudah memungkinkan entri duplikat.
dhaag23
26

Inilah jawaban BalusC , tetapi ia mengkompilasi dan mengembalikan hasil:

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
sumber
1
Catatan JVM: Saya telah mengimplementasikan bentuk yang setara ini di Scala menggunakan Java Collections; di sini adalah github gist
Jay Taylor
2
Saya sarankan mengubah String pair[] = param.split("=");menjadi String pair[] = param.split("=", 2);untuk membagi pasangan kunci = nilai hanya pada kejadian pertama. Saya percaya itu dibolehkan memiliki tanda sama dengan nilai dalam kode tidak ter-enkripsi.
Dennie
22

Jika Anda memiliki lib (server atau klien) lib di classpath Anda, Anda dapat menggunakan kelas util jetty (lihat javadoc ), misalnya:

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

Jika Anda menggunakan Spring 3.1 atau lebih besar (ya, berharap dukungan kembali lebih jauh), Anda dapat menggunakan UriComponentsdan UriComponentsBuilder:

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

components.getQueryParams() mengembalikan a MultiValueMap<String, String>

Ini beberapa dokumentasi lagi .

Nick Spacek
sumber
Ini adalah sesuatu yang saya cari. Pertanyaan saya adalah bagaimana cara mendapatkan uri? Saya terjebak dengan pemeliharaan kode yang tidak dapat saya ubah banyak dan kami tidak menggunakan HttpServlet. Alih-alih hanya menggunakan anotasi dan Pegas (@Get, @Produces (mediaType) dan @Path ("/ dataAsJSON / datafield / {datafield})) Hanya perlu tahu cara mendapatkan string kueri sehingga saya bisa menguraikannya seperti yang ditunjukkan pada contoh ini
Nelda.techspiress
5

Untuk servlet atau halaman JSP Anda bisa mendapatkan pasangan kunci / nilai querystring dengan menggunakan request.getParameter ("paramname")

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

Ada cara lain untuk melakukannya tetapi itulah cara saya melakukannya di semua servlets dan halaman jsp yang saya buat.

ChadNC
sumber
3
HttpServletRequest adalah bagian dari J2EE yang tidak dimilikinya. Juga menggunakan getParamter () tidak benar-benar parsing.
Mr. Shiny dan New New 宇
3
Luangkan waktu untuk membaca komentar di mana saya meminta klarifikasi atas pertanyaannya. Jawaban ini adalah jawaban atas jawabannya terhadap komentar di mana ia menyatakan, "Saya mencoba melakukan ini di Android, tetapi semua jawaban di semua platform akan menjadi jawaban yang berguna yang mungkin memberikan petunjuk (juga kepada orang lain yang mungkin menemukan ini) pertanyaan) jadi jangan menahan diri! " Saya menjawab pertanyaannya berdasarkan komentar itu. Jika Anda tidak memiliki sesuatu yang berguna untuk ditambahkan, jangan tambahkan apa pun
ChadNC
1
Jangan terlalu kesal. "Ini tidak menjawab pertanyaan" berguna untuk ditambahkan, IMO.
Mr. Shiny dan New New 宇
1
Tidak masalah Android atau tidak, pertanyaannya adalah bagaimana mengurai String yang berisi URL dan mengeluarkan parameter URL darinya. Apa yang Anda porting di sini adalah bagian dari Servlet API, tempat kontainer Servlet mem-parsing parameter yang masuk dari permintaan HTTP untuk Anda. Ini tidak relevan, karena pertanyaannya adalah tentang parsing String yang berisi URL, bukan permintaan HTTP, dan bukan di dalam wadah Servlet.
mvmn
5

Di Android, saya mencoba menggunakan jawaban @diyism tetapi saya menemukan masalah karakter luar angkasa yang diangkat oleh @rpetrich, misalnya: Saya mengisi formulir di mana username = "us+us"dan password = "pw pw"menyebabkan string URL terlihat seperti:

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

Namun, kode @diyism kembali "us+us"dan "pw+pw", yaitu tidak mendeteksi karakter spasi. Jika URL ditulis ulang dengan %20karakter spasi diidentifikasi:

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

Ini mengarah ke perbaikan berikut:

Uri uri = Uri.parse(url_string.replace("+", "%20"));
uri.getQueryParameter("para1");
Stephen Quan
sumber
replace(" ", "%20")ini terasa salah. Tetapi apakah trik untuk saya: D
Mārtiņš Briedis
Sintaks yang benar harus "beberapa string" .replaceAll ("[+]", "% 20");
RRTW
4

Mem-parsing string kueri sedikit lebih rumit daripada yang terlihat, tergantung pada bagaimana Anda memaafkan.

Pertama, string kueri adalah ascii byte. Anda membaca dalam byte ini satu per satu dan mengubahnya menjadi karakter. Jika karakternya adalah? atau & kemudian menandakan dimulainya nama parameter. Jika karakter adalah = maka itu menandakan dimulainya nilai paramter. Jika karakternya% maka itu menandakan dimulainya byte yang dikodekan. Di sinilah rumit.

Ketika Anda membaca di% char, Anda harus membaca dua byte berikutnya dan menafsirkannya sebagai digit hex. Itu berarti dua byte berikutnya adalah 0-9, af atau AF. Rekatkan kedua digit hex ini untuk mendapatkan nilai byte Anda. Tapi ingat, byte bukan karakter . Anda harus tahu pengkodean apa yang digunakan untuk mengkodekan karakter. Karakter é tidak mengkodekan yang sama dalam UTF-8 seperti pada ISO-8859-1. Secara umum tidak mungkin untuk mengetahui pengkodean apa yang digunakan untuk set karakter yang diberikan. Saya selalu menggunakan UTF-8 karena situs web saya dikonfigurasi untuk selalu melayani semuanya menggunakan UTF-8 tetapi dalam praktiknya Anda tidak bisa memastikan. Beberapa agen-pengguna akan memberi tahu Anda karakter penyandian dalam permintaan; Anda dapat mencoba membacanya jika Anda memiliki permintaan HTTP penuh. Jika Anda hanya memiliki url dalam isolasi, semoga berhasil.

Lagi pula, dengan asumsi Anda menggunakan UTF-8 atau pengkodean karakter multi-byte lainnya, sekarang setelah Anda mendekodekan satu byte yang dikodekan, Anda harus mengesampingkannya sampai Anda menangkap byte berikutnya. Anda memerlukan semua byte yang disandikan yang digabungkan karena Anda tidak dapat url-decode dengan benar satu byte pada suatu waktu. Sisihkan semua byte yang bersama-sama lalu dekode semuanya sekaligus untuk merekonstruksi karakter Anda.

Plus itu akan lebih menyenangkan jika Anda ingin bersikap lunak dan memperhitungkan agen pengguna yang membuat url. Sebagai contoh, beberapa klien webmail mengkodekan hal-hal. Atau gandakan? & = Karakter (misalnya:) http://yoursite.com/blah??p1==v1&&p2==v2. Jika Anda ingin mencoba menangani hal ini dengan anggun, Anda perlu menambahkan lebih banyak logika ke parser Anda.

Mr. Shiny dan New 安 宇
sumber
Itu tidak menjelaskan cara mem-parsing atau mengambil nilai
ChadNC
Benar, tapi agak rumit. Untuk itu kami sudah memiliki URLDecoder.
BalusC
2
@ChadNC: kalimat ketiga memberi tahu Anda cara mengurai: membaca dalam satu byte sekaligus dan mengonversi ke chars. Kalimat keempat memperingatkan Anda tentang karakter khusus. Dll. Mungkin Anda tidak membaca jawabannya?
Mr. Shiny dan New New 宇
@BalusC: URLDecoder berfungsi tetapi memiliki beberapa mode kegagalan jika Anda mencoba menjadi lebih lunak dalam jenis URL apa yang Anda terima.
Mr. Shiny dan New New 宇
1
Setuju dengan param parse query @ Mr.ShinyAndNew tidak mudah. Saya mendukung FIQL dan ini menjadi rasa sakit NYATA di pantat. Misalnya: yoursite.com/blah??p1==v1&&p2==v2,p2==v3;p2==v4
rafa.ferreira
4

Pada Android sederhana seperti kode di bawah ini:

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

Juga jika Anda tidak ingin mendaftarkan setiap penggunaan kunci permintaan yang diharapkan:

sanitzer.setAllowUnregisteredParamaters(true)

Sebelum menelepon:

sanitzer.parseUrl(yourUrl)
Kevin Crain
sumber
4

Saya punya metode untuk mencapai ini:

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) dan cara termudah untuk melakukan ini Menggunakan kelas 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 "";
}

dan ini adalah contoh cara menggunakan salah satu dari dua metode:

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

nilai dari tagValue adalah 800

Jorgesys
sumber
3

Di Android, Anda dapat menggunakan metode statis Uri.parse dari kelas android.net.Uri untuk melakukan tugas berat. Jika Anda melakukan sesuatu dengan URI dan Maksud, Anda ingin menggunakannya.

Patrick O'Leary
sumber
3

Hanya untuk referensi, inilah yang akhirnya saya dapatkan (berdasarkan URLEncodedUtils, dan mengembalikan Peta).

Fitur:

  • ia menerima bagian string kueri dari url (Anda dapat menggunakan request.getQueryString())
  • string kueri kosong akan menghasilkan kosong Map
  • suatu parameter tanpa nilai (? test) akan dipetakan menjadi kosong List<String>

Kode:

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

Helper kompatibilitas (nilai disimpan dalam array String seperti di 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
sumber
3

Ini berfungsi untuk saya .. Saya tidak yakin mengapa setiap orang mengejar Peta, Daftar> Yang saya butuhkan hanyalah Peta nilai nama sederhana.

Untuk mempermudah, saya menggunakan build di 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
sumber
1
bagaimana dengan formulir dengan banyak pilihan? Sangat normal untuk memiliki kunci yang diulang dalam string kueri yang sah (dan badan formulir POST). Ada cacat lain dan kasus sudut tidak tercakup; banyak dari mereka telah disebutkan dalam komentar tentang pendekatan lain. Saya akan menahan diri untuk tidak menunjuk mereka karena takut Anda memperbaikinya alih-alih menggunakan perpustakaan yang berkualitas, seperti kata - kata kasar saya dalam pertanyaan;)
Will
2

Multimap jambu biji lebih cocok untuk ini. Ini adalah versi bersih pendek:

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

Apache AXIS2 memiliki implementasi QueryStringParser.java mandiri. Jika Anda tidak menggunakan Axis2, cukup unduh kode sumber dan uji kasus dari sini -

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

Dijawab secara terbuka di sini

Di Android, ada kelas Uri dalam paket android.net . Perhatikan bahwa Uri adalah bagian dari android.net, sedangkan URI adalah bagian dari java.net.

Kelas Uri memiliki banyak fungsi untuk mengekstrak pasangan nilai kunci kueri. masukkan deskripsi gambar di sini

Fungsi berikut mengembalikan pasangan nilai kunci dalam bentuk HashMap.

Di Jawa:

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

Di 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
sumber
0

Saya tidak berpikir ada satu di JRE. Anda dapat menemukan fungsi serupa di paket lain seperti Apache HttpClient. Jika Anda tidak menggunakan paket lain, Anda hanya perlu menulis sendiri. Tidak sesulit itu. Inilah yang saya gunakan,

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
sumber
Ada apa dengan kelas apache?
Will
1
Anda dapat menggunakan metode parse (): hc.apache.org/httpcomponents-client/httpclient/apidocs/org/…
ZZ Coder
3
Harap cantumkan tautan apache commons di jawabannya sendiri sehingga saya dapat memilihnya.
itsadok
0

Berdasarkan jawaban dari BalusC, saya menulis beberapa contoh-Java-Code:

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

menggunakan Jambu Biji:

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

Menjawab di sini karena ini adalah utas populer. Ini adalah solusi bersih di Kotlin yang menggunakan UrlQuerySanitizerapi yang disarankan . Lihat dokumentasi resmi . Saya telah menambahkan pembangun string untuk menggabungkan dan menampilkan params.

    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
sumber
-2

metode ini mengambil uri dan mengembalikan peta nama par dan nilai par

  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
sumber
1
Seperti kata-kata kasar saya di atas, ini bisa dibuat sepele untuk crash. Jangan repot-repot memperbaiki, cukup gunakan perpustakaan utilitas profesional saja.
Will
-3

Anda mengatakan "Java" tetapi "bukan Java EE". Apakah maksud Anda Anda menggunakan JSP dan / atau servlet tetapi bukan tumpukan Java EE lengkap? Jika itu masalahnya, maka Anda masih harus memiliki request.getParameter () tersedia untuk Anda.

Jika Anda maksudnya Anda menulis Java tetapi Anda tidak menulis JSP atau servlet, atau bahwa Anda hanya menggunakan Java sebagai titik referensi Anda tetapi Anda berada di beberapa platform lain yang tidak memiliki parameter parsing bawaan ... Wow , itu terdengar seperti pertanyaan yang tidak mungkin, tetapi jika demikian, prinsipnya adalah:

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

(Saya bisa menulis kode Java tetapi itu tidak ada gunanya, karena jika Anda memiliki Java, Anda bisa menggunakan request.getParameters.)

Jay
sumber
hati-hati terhadap pengkodean karakter ketika url-decoding digit hex.
Mr. Shiny dan New New 宇
Ini Android, karenanya Java tetapi bukan J2EE.
Andrzej Doyle
Saya lupa menyebutkan: Anda juga perlu memeriksa "+", yang harus diterjemahkan ke spasi. Ruang tertanam adalah ilegal dalam string kueri.
Jay