372 Stimmen

Parsen einer URI-Zeichenkette in eine Name-Werte-Sammlung

Ich habe die URI so eingestellt:

https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback

Ich brauche eine Sammlung mit geparsten Elementen:

NAME               VALUE
------------------------
client_id          SS
response_type      code
scope              N_FULL
access_type        offline
redirect_uri       http://localhost/Callback

Um genau zu sein, brauche ich ein Java-Äquivalent für die C#/.NET HttpUtility.ParseQueryString Methode.

36voto

THANN Phearum Punkte 1819

Für Android, wenn Sie Folgendes verwenden OkHttp in Ihrem Projekt. Sie können sich das hier ansehen. Es ist einfach und hilfreich.

final HttpUrl url = HttpUrl.parse(query);
if (url != null) {
    final String target = url.queryParameter("target");
    final String id = url.queryParameter("id");
}

25voto

freedev Punkte 20667

PLAIN Java 11

Geben Sie die zu analysierende URL an:

URL url = new URL("https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback");

Diese Lösung sammelt eine Liste von Paaren:

List<Map.Entry<String, String>> list = Pattern.compile("&")
   .splitAsStream(url.getQuery())
   .map(s -> Arrays.copyOf(s.split("=", 2), 2))
   .map(o -> Map.entry(decode(o[0]), decode(o[1])))
   .collect(Collectors.toList());

Bei dieser Lösung wird hingegen eine Karte erfasst (da in einer URL mehrere Parameter mit gleichem Namen, aber unterschiedlichen Werten vorkommen können).

Map<String, List<String>> list = Pattern.compile("&")
   .splitAsStream(url.getQuery())
   .map(s -> Arrays.copyOf(s.split("=", 2), 2))
   .collect(groupingBy(s -> decode(s[0]), mapping(s -> decode(s[1]), toList())));

Beide Lösungen müssen eine Hilfsfunktion verwenden, um die Parameter richtig zu entschlüsseln.

private static String decode(final String encoded) {
    return Optional.ofNullable(encoded)
                   .map(e -> URLDecoder.decode(e, StandardCharsets.UTF_8))
                   .orElse(null);
}

16voto

Ramakrishna Joshi Punkte 1006

Unter Android gibt es eine Uri-Klasse im Paket Android.net . Beachten Sie, dass Uri ist Teil von Android.net in der Erwägung, dass URI ist Teil von java.net .

Die Uri-Klasse verfügt über zahlreiche Funktionen zum Extrahieren von Schlüssel-Wert-Paaren aus einer Abfrage. enter image description here

Die folgende Funktion gibt Schlüssel-Wert-Paare in Form einer HashMap zurück.

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

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

15voto

Kirby Punkte 14142

Netty bietet auch einen schönen Query-String-Parser namens QueryStringDecoder . In einer Zeile des Codes kann es die URL in der Frage analysieren. Ich mag es, weil es kein Abfangen oder Werfen von java.net.MalformedURLException .

In einer Zeile:

Map<String, List<String>> parameters = new QueryStringDecoder(url).parameters();

Siehe Javadocs hier: https://netty.io/4.1/api/io/netty/handler/codec/http/QueryStringDecoder.html

Hier ist ein kurzes, in sich geschlossenes, korrektes Beispiel:

import io.netty.handler.codec.http.QueryStringDecoder;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

public class UrlParse {

  public static void main(String... args) {
    String url = "https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback";
    QueryStringDecoder decoder = new QueryStringDecoder(url);
    Map<String, List<String>> parameters = decoder.parameters();
    print(parameters);
  }

  private static void print(final Map<String, List<String>> parameters) {
    System.out.println("NAME               VALUE");
    System.out.println("------------------------");
    parameters.forEach((key, values) ->
        values.forEach(val ->
            System.out.println(StringUtils.rightPad(key, 19) + val)));
  }
}

die Folgendes erzeugt

NAME               VALUE
------------------------
client_id          SS
response_type      code
scope              N_FULL
access_type        offline
redirect_uri       http://localhost/Callback

13voto

Ansar Ozden Punkte 467

Wenn Sie das Servlet doGet verwenden, versuchen Sie Folgendes

request.getParameterMap()

Gibt eine java.util.Map mit den Parametern dieser Anfrage zurück.

R eine unveränderliche java.util.Map, die Parameternamen als Schlüssel und Parameterwerte als Map-Werte enthält. Die Schlüssel in der Parameter-Map sind vom Typ String. Die Werte in der Parameter-Map sind vom Typ String-Array.

( [Java-Dokument](https://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getParameterMap()) )

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X