Phân tích chuỗi truy vấn trên Android


271

Java EE có ServletRequest.getParameterValues ​​() .

Trên các nền tảng không phải EE, URL.getQuery () chỉ cần trả về một chuỗi.

Cách thông thường để phân tích chính xác chuỗi truy vấn trong URL khi không có trên Java EE?


< rant >

Nó là phổ biến trong các câu trả lời để thử và tạo trình phân tích cú pháp của riêng bạn. Đây là dự án mã hóa vi mô rất thú vị và hấp dẫn, nhưng tôi không thể nói rằng đó là một ý tưởng hay :(

Các đoạn mã dưới đây thường thiếu sót hoặc bị hỏng, btw. Phá vỡ chúng là một bài tập thú vị cho người đọc. Và để tin tặc tấn công các trang web sử dụng chúng .

Phân tích chuỗi truy vấn là một vấn đề được xác định rõ nhưng đọc thông số kỹ thuật và hiểu các sắc thái là không tầm thường. Nó là tốt hơn nhiều để cho một số lập trình viên thư viện nền tảng làm công việc khó khăn, và sửa chữa, cho bạn!

< / rant >


Bạn có thể đăng một URL mẫu, những gì bạn đang nhận được getQuery()và những gì bạn muốn nhận làm đầu ra?
Thomas Owens

1
Bạn có muốn làm điều này từ một servlet hoặc một trang JSP không? Tôi cần một số làm rõ trước khi tôi trả lời.
ChadNC

1
Bạn cũng cần phân tích các tham số POST?
Thilo

2
Ngay cả khi bạn đang ở trên J2EE (hoặc trên SE với các gói EE được chọn được thêm qua OSGi, như tôi), câu hỏi này có thể có ý nghĩa. Trong trường hợp của tôi, các chuỗi POST / url được mã hóa url truy vấn được xử lý bởi một phần của hệ thống không cố ý đối với những thứ như thế ServletRequest.
Hanno Fietz

61
Được nâng cấp cho <rant />!
Nowaker

Câu trả lời:


65

Kể từ khi Android M mọi thứ trở nên phức tạp hơn. Câu trả lời của android.net.URI .getQueryParameter () có một lỗi phá vỡ khoảng trắng trước JellyBean. Apache URLEncodedUtils.parse () làm việc, nhưng đã bị phản đối trong L , và loại bỏ trong M .

Vì vậy, câu trả lời tốt nhất bây giờ là UrlQuerySanitizer . Điều này đã tồn tại kể từ API cấp 1 và vẫn tồn tại. Nó cũng khiến bạn suy nghĩ về các vấn đề phức tạp như cách bạn xử lý các ký tự đặc biệt hoặc các giá trị lặp lại.

Mã đơn giản nhất là

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

Nếu bạn hài lòng với hành vi phân tích cú pháp mặc định, bạn có thể làm:

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

nhưng bạn nên chắc chắn rằng bạn hiểu hành vi phân tích cú pháp mặc định là gì, vì nó có thể không phải là điều bạn muốn.


4
URLQuerySanitizer.get ALLButNullLegal () trả về UrlQuerySanitizer.ValueSanitizer, không phải UrlQuerySanitizer.
Peter Zhao

31
Vì một số lý do, những điều trên không hiệu quả với tôi, tôi đã phải sửa đổi nó một chút - điều này làm cho nó thậm chí còn dễ dàng hơn:UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(YourStringURL); String value = sanitizer.getValue("parameter");
SeBsZ

3
Không làm việc. UrlQuerySanitizer trong sdk-23 chỉ có một phương thứcsanitize()
Ninja

Điều này sẽ giải mã các ký tự đặc biệt và biểu tượng cảm xúc _. Tôi đã phải đi với stackoverflow.com/a/35638979/1155282
Irshu

Có một thư viện khung tương đương mùa xuân này?
iamjoshua

202

Trên Android:

import android.net.Uri;

[...]

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

20
lưu ý rằng điều này sử dụng lớp Uri chứ không phải lớp URI (Uri là một phần của android.net, trong khi URI là một phần của java.net)
Marius

5
Cũng lưu ý rằng trước Ice Cream Sandwich, điều này không thể phân tích cú pháp + ký tự trong các giá trị thành ký tự khoảng trắng.
rpetrich

@rpetrich thực sự các tài liệu nói rằng lỗi là trước Jelly Bean, bao gồm cả Ice Cream Sandwich. ref
Big McLargeHuge

64

9
Điều này có sẵn trong thư viện máy khách http apache, không chỉ trên Android. Btw, liên kết đến apache đã được thay đổi. Mới nhất là: hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/ Kẻ
Cristian Vrabie

9
Khó chịu URLEncodedUtils.parse()trả về một Listcái mà sau đó bạn sẽ phải lặp lại để tìm giá trị cho một khóa cụ thể. Sẽ tốt hơn nhiều nếu trả lời Mapgiống như trong câu trả lời của BalusC.
Asaph

1
@Hanno Fietz bạn có nghĩa là bạn tin tưởng những lựa chọn thay thế này? Tôi biết họ có lỗi. Tôi biết việc chỉ ra các lỗi tôi thấy sẽ chỉ khuyến khích mọi người chấp nhận các phiên bản 'đã sửa', thay vì tự tìm kiếm các lỗi mà tôi đã bỏ qua.
Sẽ

1
@ Will - tốt, tôi sẽ không bao giờ tin tưởng vào các đoạn sao chép và dán tôi nhận được từ bất kỳ trang web nào, và không ai nên làm. Nhưng ở đây, những đoạn trích này được đánh giá và nhận xét khá tốt và do đó arethực sự hữu ích. Chỉ cần nhìn thấy một số gợi ý về những gì có thể sai với mã đã giúp ích rất nhiều cho việc suy nghĩ của tôi. Và nhớ cho bạn, tôi không có ý nói "cuộn của riêng bạn là tốt hơn", nhưng đúng hơn là thật tuyệt khi có tài liệu tốt cho một quyết định sáng suốt trong mã của riêng tôi.
Hanno Fietz

8
Tôi tưởng tượng parse trả về một danh sách để nó duy trì thứ tự vị trí và dễ dàng cho phép các mục trùng lặp hơn.
dhaag23

26

Đây là câu trả lời của BalusC , nhưng nó biên dịch và trả về kết quả:

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 Lưu ý: Tôi đã triển khai một dạng tương đương của điều này trong Scala bằng cách sử dụng Bộ sưu tập Java; đây là ý chính của github: gist.github.com/3504765
Jay Taylor

2
Tôi đề nghị thay đổi String pair[] = param.split("=");vào String pair[] = param.split("=", 2);để phân chia các khóa = giá trị cặp chỉ về sự xuất hiện đầu tiên. Tôi tin rằng nó được phép có các dấu bằng không được mã hóa trong giá trị.
Dennie

22

Nếu bạn có lib cầu tàu (máy chủ hoặc máy khách) trên đường dẫn lớp của mình, bạn có thể sử dụng các lớp sử dụng cầu cảng (xem javadoc ), ví dụ:

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

Nếu bạn đang sử dụng Spring 3.1 trở lên (yike, hy vọng rằng sự hỗ trợ sẽ quay trở lại), bạn có thể sử dụng UriComponentsUriComponentsBuilder:

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

components.getQueryParams() trả lại một MultiValueMap<String, String>

Dưới đây là một số tài liệu .


Đây là thứ tôi đang tìm kiếm. Câu hỏi của tôi là làm thế nào để tôi có được uri? Tôi bị mắc kẹt với việc bảo trì mã mà tôi không thể thay đổi nhiều và chúng tôi không sử dụng HttpServlet. Thay vào đó chỉ sử dụng chú thích và Spring (@Get, @ sản phẩm (mediaType) và @Path ("/ dataAsJSON / datafield / {datafield})) Chỉ cần biết cách lấy chuỗi truy vấn để tôi có thể phân tích cú pháp như được hiển thị trong ví dụ này.
Nelda.techspiress 11/03/2016

5

Đối với một servlet hoặc một trang JSP, bạn có thể nhận được các cặp khóa / giá trị chuỗi truy vấn bằng cách sử dụng request.getParameter ("paramname")

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

Có nhiều cách khác để làm điều đó nhưng đó là cách tôi làm trong tất cả các trang dịch vụ và jsp mà tôi tạo.


3
HttpServletRequest là một phần của J2EE mà anh không có. Ngoài ra, sử dụng getParamter () không thực sự phân tích cú pháp.
Ông Shiny và New

3
Hãy dành thời gian để đọc bình luận trong đó tôi yêu cầu làm rõ câu hỏi của anh ấy. Câu trả lời này là để đáp lại câu trả lời của anh ấy cho nhận xét đó, trong đó anh ấy đã nói, "Tôi đang cố gắng làm điều này trên Android, nhưng tất cả các câu trả lời trên tất cả các nền tảng sẽ là câu trả lời hữu ích có thể đưa ra gợi ý (cũng cho những người khác có thể gặp phải điều này câu hỏi) vì vậy đừng giữ lại! " Tôi trả lời câu hỏi của anh ấy dựa trên nhận xét đó. Nếu bạn không có gì hữu ích để thêm, đừng thêm bất cứ thứ gì
ChadNC

1
Đừng quá buồn. "Điều này không trả lời câu hỏi" rất hữu ích để thêm, IMO.
Ông Shiny và New

1
Không quan trọng Android hay không, câu hỏi là làm thế nào để phân tích Chuỗi chứa URL và lấy tham số URL ra khỏi nó. Những gì bạn đang chuyển ở đây là một phần của API Servlet, nơi bộ chứa Servlet phân tích các tham số đến từ yêu cầu HTTP cho bạn. Điều đó không liên quan, bởi vì câu hỏi là về phân tích chuỗi có chứa URL, không phải yêu cầu HTTP và không nằm trong vùng chứa Servlet.
mvmn

5

Trên Android, tôi đã thử sử dụng câu trả lời @diyism nhưng tôi gặp phải vấn đề về ký tự không gian được nêu ra bởi @rpetrich, ví dụ: Tôi điền vào một biểu mẫu trong đó username = "us+us"password = "pw pw"khiến một chuỗi URL trông giống như:

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

Tuy nhiên, mã @diyism trả về "us+us""pw+pw", tức là nó không phát hiện ký tự khoảng trắng . Nếu URL được viết lại với %20ký tự khoảng trắng được xác định:

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

Điều này dẫn đến sửa chữa sau:

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

replace(" ", "%20")Điều này cảm thấy sai. Nhưng đã lừa tôi: D
Mārtiņš Briedis

Cú pháp đúng phải là "một số chuỗi" .replaceAll ("[+]", "% 20");
RRTW

4

Phân tích chuỗi truy vấn phức tạp hơn một chút so với vẻ ngoài của nó, tùy thuộc vào mức độ bạn muốn tha thứ.

Đầu tiên, chuỗi truy vấn là byte ascii. Bạn đọc từng byte một và chuyển đổi chúng thành các ký tự. Nếu là nhân vật? hoặc & sau đó nó báo hiệu bắt đầu một tên tham số. Nếu ký tự là = thì nó báo hiệu bắt đầu một giá trị tham số. Nếu ký tự là% thì nó báo hiệu bắt đầu một byte được mã hóa. Đây là nơi nó trở nên khó khăn.

Khi bạn đọc bằng% char, bạn phải đọc hai byte tiếp theo và hiểu chúng là các chữ số hex. Điều đó có nghĩa là hai byte tiếp theo sẽ là 0-9, af hoặc AF. Dán hai chữ số hex này lại với nhau để lấy giá trị byte của bạn. Nhưng hãy nhớ rằng, byte không phải là ký tự . Bạn phải biết mã hóa nào đã được sử dụng để mã hóa các ký tự. Ký tự é không mã hóa giống nhau trong UTF-8 như trong ISO-8859-1. Nói chung, không thể biết mã hóa nào được sử dụng cho một bộ ký tự nhất định. Tôi luôn sử dụng UTF-8 vì trang web của tôi được định cấu hình để luôn phục vụ mọi thứ bằng UTF-8 nhưng trong thực tế, bạn không thể chắc chắn. Một số tác nhân người dùng sẽ cho bạn biết mã hóa ký tự trong yêu cầu; bạn có thể thử đọc nó nếu bạn có một yêu cầu HTTP đầy đủ. Nếu bạn chỉ có một url trong sự cô lập, chúc may mắn.

Dù sao, giả sử bạn đang sử dụng UTF-8 hoặc một số mã hóa ký tự nhiều byte khác, bây giờ bạn đã giải mã được một byte được mã hóa, bạn phải đặt nó sang một bên cho đến khi bạn bắt được byte tiếp theo. Bạn cần tất cả các byte được mã hóa cùng nhau vì bạn không thể giải mã url đúng một byte mỗi lần. Đặt tất cả các byte cùng nhau sau đó giải mã tất cả chúng cùng một lúc để tái cấu trúc nhân vật của bạn.

Thêm vào đó, nó sẽ trở nên thú vị hơn nếu bạn muốn được khoan dung và giải thích cho các tác nhân người dùng sử dụng url. Ví dụ, một số khách hàng webmail mã hóa hai thứ. Hoặc nhân đôi ký tự? & = (Ví dụ http://yoursite.com/blah??p1==v1&&p2==v2:). Nếu bạn muốn cố gắng xử lý một cách duyên dáng với điều này, bạn sẽ cần thêm logic hơn vào trình phân tích cú pháp của mình.


Điều đó không giải thích cách phân tích hoặc truy xuất các giá trị tham số chuỗi truy vấn
ChadNC

Phải, nhưng hơi cồng kềnh. Cho rằng chúng tôi đã có URLDecoder.
BalusC

2
@ChadNC: câu thứ ba cho bạn biết cách phân tích: đọc từng byte một và chuyển thành ký tự. Câu thứ tư cảnh báo bạn về ký tự đặc biệt. V.v. Có lẽ bạn đã không đọc câu trả lời?
Ông Shiny và New 安 安

@BalusC: URLDecoder hoạt động nhưng nó có một số chế độ thất bại nếu bạn đang cố gắng trở nên khoan dung hơn trong loại URL nào bạn chấp nhận.
Ông Shiny và New

1
Đồng ý với thông số truy vấn phân tích cú pháp @ Mr.ShinyAndNew không dễ dàng. Tôi đang hỗ trợ FIQL và điều này trở thành một nỗi đau thực sự ở mông. Ví dụ: yoursite.com/blah??p1==v1&&p2==v2,p2==v3;p2==v4
rafa.ferreira

4

Trên Android đơn giản như mã dưới đây:

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

Ngoài ra nếu bạn không muốn đăng ký sử dụng khóa truy vấn dự kiến:

sanitzer.setAllowUnregisteredParamaters(true)

Trước khi gọi:

sanitzer.parseUrl(yourUrl)

4

Tôi có phương pháp để đạt được điều này:

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) và cách dễ nhất để làm điều này bằng cách sử dụng lớp 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 "";
}

và đây là một ví dụ về cách sử dụng một trong hai phương pháp:

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

giá trị của tagValue là 800


3

Trên Android, bạn có thể sử dụng phương thức tĩnh Uri.parse của lớp android.net.Uri để thực hiện các công việc nặng. Nếu bạn đang làm bất cứ điều gì với URI và Ý định, bạn sẽ muốn sử dụng nó.


3

Chỉ để tham khảo, đây là những gì tôi đã kết thúc (dựa trên URLEncodingUtils và trả về Bản đồ).

Đặc trưng:

  • nó chấp nhận phần chuỗi truy vấn của url (bạn có thể sử dụng request.getQueryString())
  • một chuỗi truy vấn trống sẽ tạo ra một khoảng trống Map
  • một tham số không có giá trị (? test) sẽ được ánh xạ tới chỗ trống List<String>

Mã số:

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

Trình trợ giúp tương thích (các giá trị được lưu trữ trong một chuỗi Chuỗi giống như trong 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;
}

3

Điều này hiệu quả với tôi .. Tôi không chắc tại sao mọi người lại theo sau Bản đồ, Danh sách> Tất cả những gì tôi cần là một giá trị tên đơn giản Bản đồ.

Để đơn giản, tôi đã sử dụng bản dựng trong 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
làm thế nào về các hình thức với nhiều lựa chọn? Hoàn toàn bình thường khi có các khóa được lặp lại trong các chuỗi truy vấn hợp pháp (và các thân biểu mẫu POST). Có những khiếm khuyết khác và các trường hợp góc không được bảo hiểm; nhiều trong số chúng đã được đề cập trong bình luận về các phương pháp khác. Tôi sẽ kiềm chế hình thức chỉ ra chúng vì sợ rằng bạn sửa nó thay vì sử dụng một thư viện chất lượng, theo như câu nói của tôi trong câu hỏi;)
Sẽ

2

Multimap của Guava phù hợp hơn cho việc này. Đây là một phiên bản sạch ngắn:

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

Apache AXIS2 có một triển khai độc lập của QueryStringParser.java. Nếu bạn không sử dụng Axis2, chỉ cần tải xuống mã nguồn và trường hợp thử nghiệm từ đây -

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

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


1

Trả lời bằng cách này

Trên Android, có lớp Uri trong gói android.net . Lưu ý rằng Uri là một phần của android.net, trong khi URI là một phần của java.net.

Lớp Uri có nhiều hàm để trích xuất các cặp khóa-giá trị truy vấn. nhập mô tả hình ảnh ở đây

Hàm sau trả về các cặp khóa-giá trị dưới dạng HashMap.

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

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

0

Tôi không nghĩ có một cái trong JRE. Bạn có thể tìm thấy các hàm tương tự trong các gói khác như Apache HttpClient. Nếu bạn không sử dụng bất kỳ gói nào khác, bạn chỉ cần viết riêng của bạn. Nó không khó lắm đâu. Đây là những gì tôi sử dụng,

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

Cách nào với các lớp apache?
Sẽ

1
Bạn có thể sử dụng phương thức parse (): hc.apache.org/httpcomponents-client/httpclient/apidocs/org/ Kẻ
ZZ Coder

3
Vui lòng đặt liên kết apache commons trong câu trả lời của riêng mình để tôi có thể bỏ phiếu.
itadok

0

Dựa trên câu trả lời từ BalusC, tôi đã viết một số ví dụ về Mã 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
            }
        }
    }

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

sử dụng ổi:

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

Trả lời ở đây vì đây là một chủ đề phổ biến. Đây là một giải pháp sạch trong Kotlin sử dụng UrlQuerySanitizerapi được đề xuất . Xem tài liệu chính thức . Tôi đã thêm một trình xây dựng chuỗi để nối và hiển thị các thông số.

    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

phương pháp này lấy bản đồ uri và trả về mệnh giá và mệnh giá

  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
Theo lời nói của tôi ở trên, điều này có thể được thực hiện để sụp đổ. Đừng bận tâm sửa chữa, thay vào đó chỉ sử dụng một thư viện tiện ích chuyên nghiệp.
Sẽ

-3

Bạn nói "Java" nhưng "không phải Java EE". Bạn có nghĩa là bạn đang sử dụng JSP và / hoặc servlets nhưng không phải là một ngăn xếp Java EE đầy đủ? Nếu đó là trường hợp, thì bạn vẫn nên có request.getParameter () có sẵn cho bạn.

Nếu bạn có nghĩa là bạn đang viết Java nhưng bạn không viết JSP hay servlet hoặc bạn chỉ đang sử dụng Java làm điểm tham chiếu của mình nhưng bạn đang ở một nền tảng khác không có phân tích cú pháp tham số tích hợp ... Wow , đó chỉ là một câu hỏi không thể, nhưng nếu vậy, nguyên tắc sẽ là:

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

(Tôi có thể viết mã Java nhưng điều đó là vô nghĩa, bởi vì nếu bạn có sẵn Java, bạn chỉ có thể sử dụng request.getParameter.)


coi chừng mã hóa ký tự khi giải mã url các chữ số hex.
Ông Shiny và New 安 安

Đó là Android, do đó là Java nhưng không phải là J2EE.
Andrzej Doyle

Tôi quên đề cập: Bạn cũng cần kiểm tra "+", cần được dịch sang một khoảng trắng. Không gian nhúng là bất hợp pháp trong một chuỗi truy vấn.
Jay
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.