2010-11-08 15 views
17

Qualcuno ha o conosce una classe java che posso utilizzare per manipolare le stringhe di query?Manipolazione stringa di query in Java

In sostanza mi piacerebbe una classe che possa semplicemente fornire una stringa di query e quindi eliminare, aggiungere e modificare la stringa di query KVP.

Grazie in anticipo.

EDIT

In risposta ad un commento fatto a questa domanda, la stringa di query sarà simile a questa;

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

Quindi mi piacerebbe passare questa classe alla stringa di query e dire qualcosa del tipo;

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

e poi magari

queryStringClass.setParameter("N", N); 

e forse queryStringClass.removeParameter("N");

O qualcosa in tal senso.

+3

Non hai fornito un contesto sufficiente per consentire a nessuno di rispondere. Che tipo di stringhe di query? Si prega di riformulare la domanda. –

+1

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

risposta

16

qualcosa di simile

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

per scorrere la mappa semplicemente:

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

Mi piacerebbe avere qualcosa di pre-costruito ma questo è fantastico. :) grazie – griegs

+1

Sarebbe più efficiente memorizzare 'param.split (" = ")' in una variabile e riutilizzare il risultato anziché dividere lo stesso parametro due volte. – LeastOne

+7

Questa soluzione non tiene conto dei caratteri di escape. – raulk

0

È possibile creare un metodo di util e utilizzare espressioni regolari per analizzarlo. Un modello come "[; &]" dovrebbe essere sufficiente.

5

Se si utilizza J2EE, è possibile utilizzare ServletRequest.getParameterValues().

In caso contrario, non credo che Java abbia classi comuni per la gestione della stringa di query. Scrivere il proprio non dovrebbe essere troppo difficile, anche se ci sono alcuni casi complicati, come rendersi conto che tecnicamente la stessa chiave può apparire più di una volta nella stringa di query.

Un'implementazione potrebbe essere simile:

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, grazie per questo. Già implementato qualcosa di simile. – griegs

+0

Come lavorare con "&" nel mezzo di stringhe di query? – Achimnol

+0

@Achimnol: Qual è il problema? & è codifica XML, deve passare attraverso un parametro URL come% 26amp ;. Se si desidera ulteriormente decodificare la stringa in XML, è possibile utilizzare altri metodi. – Avi

12

È inoltre possibile utilizzare divisore di Google Guava.

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

stampe fuori

89 

Questo credo sia un molto leggibile alternativa ad analisi da soli.

Modifica: come sottolineato da @raulk, questa soluzione non tiene conto dei caratteri di escape. Tuttavia, questo potrebbe non essere un problema perché prima di decodificare l'URL, la stringa di query è garantita per non avere caratteri di escape in conflitto con '=' e '&'. Puoi usare questo a tuo vantaggio nel modo seguente.

dire che si deve decodificare la seguente stringa di query:

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

che è URL codificato, quindi si ha la garanzia che il '&' e '=' sono specificamente utilizzati per separare coppie e chiave dal valore, rispettivamente, a questo punto è possibile utilizzare lo splitter Guava per ottenere:

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

Dopo aver ottenuto le coppie di valori-chiave, allora si può decodificare URL separatamente.

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

Che dovrebbe coprire tutti i casi.

+6

Questo soluzione non tiene conto dei caratteri di escape. – raulk

+0

Avresti ragione. –

+0

@raulk Ho aggiunto alcuni passaggi che potrebbero essere utilizzati anche con caratteri di escape. Grazie! –

1

Un altro modo è utilizzare i componenti http di Apache. E 'un po' hacky, ma almeno si sfruttare tutti i casi d'angolo di analisi:

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

Questo ti darà una lista di oggetti NameValuePair che dovrebbe essere facile da lavorare.

+0

Ho trovato strano che questo non fosse già proposto ... questo è hacky ma un buon uso di una libreria esistente ... – AxelH