349 votes

Analyser la chaîne Uri dans la collection nom-valeur en java

J'ai l'URI comme ceci:

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

J'ai besoin d'un collection avec analysée éléments:

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

Pour être exact, j'ai besoin d'un Java équivalent en C# HttpUtility.ParseQueryString Méthode. S'il vous plaît, me donner un conseil sur ce. Merci.

414voto

Pr0gr4mm3r Points 1388

Si vous êtes à la recherche d'un moyen de l'atteindre sans l'aide d'une bibliothèque externe, le code suivant va vous aider.

public static Map<String, String> splitQuery(URL url) throws UnsupportedEncodingException {
    Map<String, String> query_pairs = new LinkedHashMap<String, String>();
    String query = url.getQuery();
    String[] pairs = query.split("&");
    for (String pair : pairs) {
        int idx = pair.indexOf("=");
        query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
    }
    return query_pairs;
}

Vous pouvez accéder à l'retourné la Carte en utilisant l' <map>.get("client_id"), avec l'URL donnée dans votre question, ce serait de retour "SS".

Mise à JOUR de l'URL de Décodage ajouté

Mise à JOUR Que cette réponse est encore très populaire, j'ai fait une version améliorée de la méthode ci-dessus, qui gère plusieurs paramètres avec la même clé et les paramètres sans valeur.

public static Map<String, List<String>> splitQuery(URL url) throws UnsupportedEncodingException {
  final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
  final String[] pairs = url.getQuery().split("&");
  for (String pair : pairs) {
    final int idx = pair.indexOf("=");
    final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
    if (!query_pairs.containsKey(key)) {
      query_pairs.put(key, new LinkedList<String>());
    }
    final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
    query_pairs.get(key).add(value);
  }
  return query_pairs;
}

L'exécution de la méthode ci-dessus avec l'URL "http://stackoverflow.com?param1=value1&param2=&param3=value3&param3" retourne cette Carte: {param1=["valeur1"], param2=[null], param3=["valeur3", null]}

378voto

Juan Mendes Points 31678

http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/utils/URLEncodedUtils.html est une bibliothèque bien connue qui peut le faire pour vous.

 String url = "http://www.example.com/something.html?one=11111&two=22222&three=33333";
List<NameValuePair> params = URLEncodedUtils.parse(new URI(url), "UTF-8");

for (NameValuePair param : params) {
  System.out.println(param.getName() + " : " + param.getValue());
}
 

Les sorties

un: 11111

deux: 22222

trois: 33333

59voto

Amin Abbaspour Points 167

utilisez google guava et faites le en 2 lignes:

 import java.util.Map;
import com.google.common.base.Splitter;

public class Parser {
    public static void main(String... args) {
        String uri = "https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback";
        String query = uri.split("\\?")[1];
        final Map<String, String> map = Splitter.on('&').trimResults().withKeyValueSeparator("=").split(query);
        System.out.println(map);
    }
}
 

qui te donne

 {client_id=SS, response_type=code, scope=N_FULL, access_type=offline, redirect_uri=http://localhost/Callback}
 

0voto

Edy Bourne Points 401

Ou, si vous souhaitez utiliser l'implémentation de la bibliothèque Apache HttpComponents comme je l'ai fait et que vous ne souhaitez pas inclure l'ensemble dans le but d'analyser une URL, vous pouvez supprimer uniquement les parties pertinentes et vivre la bibliothèque:

 private static final char QP_SEP_A = '&';
private static final char QP_SEP_S = ';';
private static final String NAME_VALUE_SEPARATOR = "=";

/**
 * Query parameter separators.
 */
private static final char[] QP_SEPS = new char[] { QP_SEP_A, QP_SEP_S };

/**
 * Query parameter separator pattern.
 */
private static final String QP_SEP_PATTERN = "[" + new String(QP_SEPS)
        + "]";

 /**
 * Returns a list of {@link NameValuePair NameValuePairs} as built from the URI's query portion. For example, a URI
 * of http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three NameValuePairs, one for a=1, one for
 * b=2, and one for c=3. By convention, {@code '&'} and {@code ';'} are accepted as parameter separators.
 * <p>
 * This is typically useful while parsing an HTTP PUT.
 *
 * This API is currently only used for testing.
 *
 * @param uri
 *            URI to parse
 * @param charset
 *            Charset name to use while parsing the query
 * @return a list of {@link NameValuePair} as built from the URI's query portion.
 */
public static List <NameValuePair> parse(final URI uri, final String charset) {
    final String query = uri.getRawQuery();
    if (query != null && query.length() > 0) {
        final List<NameValuePair> result = new ArrayList<NameValuePair>();
        final Scanner scanner = new Scanner(query);
        parse(result, scanner, QP_SEP_PATTERN, charset);
        return result;
    }
    return Collections.emptyList();
}


/**
 * Adds all parameters within the Scanner to the list of
 * <code>parameters</code>, as encoded by <code>encoding</code>. For
 * example, a scanner containing the string <code>a=1&b=2&c=3</code> would
 * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the
 * list of parameters.
 *
 * @param parameters
 *            List to add parameters to.
 * @param scanner
 *            Input that contains the parameters to parse.
 * @param parameterSepartorPattern
 *            The Pattern string for parameter separators, by convention {@code "[&;]"}
 * @param charset
 *            Encoding to use when decoding the parameters.
 */
public static void parse(
        final List <NameValuePair> parameters,
        final Scanner scanner,
        final String parameterSepartorPattern,
        final String charset) {
    scanner.useDelimiter(parameterSepartorPattern);
    while (scanner.hasNext()) {
        String name = null;
        String value = null;
        final String token = scanner.next();
        final int i = token.indexOf(NAME_VALUE_SEPARATOR);
        if (i != -1) {
            name = decodeFormFields(token.substring(0, i).trim(), charset);
            value = decodeFormFields(token.substring(i + 1).trim(), charset);
        } else {
            name = decodeFormFields(token.trim(), charset);
        }
        parameters.add(new NameValuePair(name, value));
    }
}


/**
 * Decode/unescape www-url-form-encoded content.
 *
 * @param content the content to decode, will decode '+' as space
 * @param charset the charset to use
 * @return encoded string
 */
private static String decodeFormFields (final String content, final String charset) {
    if (content == null) {
        return null;
    }
    return urlDecode(content, charset != null ? Charset.forName(charset) : Charset.forName("UTF-8"), true);
}

/**
 * Decode/unescape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true.
 *
 * @param content the portion to decode
 * @param charset the charset to use
 * @param plusAsBlank if {@code true}, then convert '+' to space (e.g. for www-url-form-encoded content), otherwise leave as is.
 * @return encoded string
 */
private static String urlDecode(
        final String content,
        final Charset charset,
        final boolean plusAsBlank) {
    if (content == null) {
        return null;
    }
    final ByteBuffer bb = ByteBuffer.allocate(content.length());
    final CharBuffer cb = CharBuffer.wrap(content);
    while (cb.hasRemaining()) {
        final char c = cb.get();
        if (c == '%' && cb.remaining() >= 2) {
            final char uc = cb.get();
            final char lc = cb.get();
            final int u = Character.digit(uc, 16);
            final int l = Character.digit(lc, 16);
            if (u != -1 && l != -1) {
                bb.put((byte) ((u << 4) + l));
            } else {
                bb.put((byte) '%');
                bb.put((byte) uc);
                bb.put((byte) lc);
            }
        } else if (plusAsBlank && c == '+') {
            bb.put((byte) ' ');
        } else {
            bb.put((byte) c);
        }
    }
    bb.flip();
    return charset.decode(bb).toString();
}
public static class NameValuePair {

    private String value;

    private String name;

    public NameValuePair(String value, String name) {
        this.value = value;
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
 

Puis invoquez-le comme @Juan Mendes l'a fait dans sa réponse.

J'espère que cela pourra aider!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X