2010-11-08 63 views
17

Có ai có, hoặc biết, một lớp java mà tôi có thể sử dụng để thao tác chuỗi truy vấn không?Thao tác chuỗi truy vấn trong Java

Về cơ bản tôi muốn một lớp mà tôi có thể chỉ đơn giản là đưa ra một chuỗi truy vấn và sau đó xóa, thêm và sửa đổi chuỗi truy vấn của KVP.

Xin cảm ơn trước.

EDIT

Đáp lại nhận xét có cho câu hỏi này, chuỗi truy vấn sẽ giống như thế này;

N=123+456+112&Ntt=koala&D=abc 

Vì vậy, tôi muốn chuyển lớp này chuỗi truy vấn và nói điều gì đó tương tự;

String[] N = queryStringClass.getParameter("N"); 

và sau đó có lẽ

queryStringClass.setParameter("N", N); 

và có thể queryStringClass.removeParameter("N");

Hoặc một cái gì đó về việc đó.

+3

Bạn chưa cung cấp đủ ngữ cảnh cho bất kỳ ai đưa ra câu trả lời. Loại chuỗi truy vấn nào? Vui lòng lặp lại câu hỏi. –

+1

http://stackoverflow.com/questions/1667278/parsing-query-strings-in-java –

Trả lời

16

một cái gì đó như thế này

public static Map<String, String> getQueryMap(String query) 
{ 
    String[] params = query.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); 
    } 
    return map; 
} 

Để lặp bản đồ đơn giản:

String query = url.getQuery(); 
Map<String, String> map = getQueryMap(query); 
Set<String> keys = map.keySet(); 
for (String key : keys) 
{ 
    System.out.println("Name=" + key); 
    System.out.println("Value=" + map.get(key)); 
} 
+0

Rất thích có điều gì đó được xây dựng sẵn nhưng điều này thật tuyệt vời. :) cảm ơn bạn – griegs

+1

Sẽ hiệu quả hơn khi lưu trữ 'param.split (" = ")' trong một biến và sử dụng lại kết quả trái ngược với việc tách cùng một tham số hai lần. – LeastOne

+7

Giải pháp này không tính đến các ký tự thoát. – raulk

0

Bạn có thể tạo một phương pháp util và sử dụng biểu thức chính quy để phân tích nó. Một mẫu như "[; &]" là đủ.

5

Nếu bạn đang sử dụng J2EE, bạn có thể sử dụng ServletRequest.getParameterValues().

Nếu không, tôi không nghĩ Java có bất kỳ lớp phổ biến nào để xử lý chuỗi truy vấn. Viết của riêng bạn không nên quá khó, mặc dù có một số trường hợp khó khăn cạnh, chẳng hạn như nhận ra rằng kỹ thuật cùng một khóa có thể xuất hiện nhiều hơn một lần trong chuỗi truy vấn.

Một thi thể hình như:

import java.util.*; 
import java.net.URLEncoder; 
import java.net.URLDecoder; 

public class QueryParams { 
private static class KVP { 
    final String key; 
    final String value; 
    KVP (String key, String value) { 
     this.key = key; 
     this.value = value; 
    } 
} 

List<KVP> query = new ArrayList<KVP>(); 

public QueryParams(String queryString) { 
    parse(queryString); 
} 

public QueryParams() { 
} 

public void addParam(String key, String value) { 
    if (key == null || value == null) 
     throw new NullPointerException("null parameter key or value"); 
    query.add(new KVP(key, value)); 
} 

private void parse(String queryString) { 
    for (String pair : queryString.split("&")) { 
     int eq = pair.indexOf("="); 
     if (eq < 0) { 
      // key with no value 
      addParam(URLDecoder.decode(pair), ""); 
     } else { 
      // key=value 
      String key = URLDecoder.decode(pair.substring(0, eq)); 
      String value = URLDecoder.decode(pair.substring(eq + 1)); 
      query.add(new KVP(key, value)); 
     } 
    } 
} 

public String toQueryString() { 
    StringBuilder sb = new StringBuilder(); 
    for (KVP kvp : query) { 
     if (sb.length() > 0) { 
      sb.append('&'); 
     } 
     sb.append(URLEncoder.encode(kvp.key)); 
     if (!kvp.value.equals("")) { 
      sb.append('='); 
      sb.append(URLEncoder.encode(kvp.value)); 
     } 
    } 
    return sb.toString(); 
} 

public String getParameter(String key) { 
    for (KVP kvp : query) { 
     if (kvp.key.equals(key)) { 
      return kvp.value; 
     } 
    } 
    return null; 
} 

public List<String> getParameterValues(String key) { 
    List<String> list = new LinkedList<String>(); 
    for (KVP kvp : query) { 
     if (kvp.key.equals(key)) { 
      list.add(kvp.value); 
     } 
    } 
    return list; 
} 

public static void main(String[] args) { 
    QueryParams qp = new QueryParams("k1=v1&k2&k3=v3&k1=v4&k1&k5=hello+%22world"); 
    System.out.println("getParameter:"); 
    String[] keys = new String[] { "k1", "k2", "k3", "k5" }; 
    for (String key : keys) { 
     System.out.println(key + ": " + qp.getParameter(key)); 
    } 
    System.out.println("getParameters(k1): " + qp.getParameterValues("k1")); 
} 
} 
+0

+1, cảm ơn vì điều này. Đã thực hiện một cái gì đó như thế này. – griegs

+0

Làm cách nào để làm việc với "&" ở giữa các chuỗi truy vấn? – Achimnol

+0

@Achimnol: Có vấn đề gì? & là mã hóa XML, nó phải chuyển qua tham số URL dưới dạng% 26amp ;. Nếu bạn muốn tiếp tục giải mã chuỗi XML, bạn có thể sử dụng các phương thức khác cho chuỗi đó. – Avi

12

Bạn cũng có thể sử dụng Splitter Google ổi của.

String queryString = "variableA=89&variableB=100"; 
Map<String,String> queryParameters = Splitter 
    .on("&") 
    .withKeyValueSeparator("=") 
    .split(queryString); 
System.out.println(queryParameters.get("variableA")); 

in ra

89 

này tôi nghĩ là một lựa chọn rất có thể đọc được để phân tích nó cho mình.

Chỉnh sửa: Như @raulk đã chỉ ra, giải pháp này không tính đến các ký tự thoát. Tuy nhiên, điều này có thể không phải là một vấn đề bởi vì trước khi bạn giải mã URL, chuỗi truy vấn được đảm bảo không có bất kỳ ký tự thoát nào xung đột với '=' và '&'. Bạn có thể sử dụng điều này để lợi thế của bạn theo cách sau.

Nói rằng bạn phải giải mã các chuỗi truy vấn sau đây:

a=%26%23%25!)%23(%40!&b=%23%24(%40)%24%40%40))%24%23%5E*%26 

được URL mã hóa, sau đó bạn được đảm bảo rằng '&' và '=' được sử dụng đặc biệt để tách cặp và chìa khóa từ giá trị, tương ứng, tại thời điểm đó bạn có thể sử dụng bộ tách ổi để nhận được:

a = %26%23%25!)%23(%40! 
b = %23%24(%40)%24%40%40))%24%23%5E*%26 

Khi bạn đã có được cặp khóa-giá trị, thì bạn có thể giải mã chúng một cách riêng biệt.

a = &#%!)#(@! 
b = #$(@)[email protected]@))$#^*& 

Điều đó phải bao gồm tất cả các trường hợp.

+6

Điều này giải pháp không tính đến các ký tự thoát. – raulk

+0

Bạn sẽ đúng. –

+0

@raulk Tôi đã thêm một số bước có thể được sử dụng ngay cả với các ký tự thoát. Cảm ơn! –

1

Một cách khác là sử dụng các thành phần http apache. Đó là một chút hacky, nhưng ít nhất bạn tận dụng tất cả các trường hợp góc phân tích cú pháp:

List<NameValuePair> params = 
    URLEncodedUtils.parse("http://example.com/?" + queryString, Charset.forName("UTF-8")); 

Điều đó sẽ cung cấp cho bạn một danh sách các đối tượng NameValuePair rằng nên dễ làm việc với.

+0

Tôi thấy lạ rằng điều này đã không được đề xuất ... đây là hacky nhưng một cách sử dụng tốt của một thư viện hiện có ... – AxelH