Ik heb de URI als volgt:
https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback
Ik heb een verzameling nodig met geparseerde elementen:
NAME VALUE
------------------------
client_id SS
response_type code
scope N_FULL
access_type offline
redirect_uri http://localhost/Callback
Om precies te zijn, ik heb een Java-equivalent nodig voor de C#/.NET HttpUtility.ParseQueryString
-methode.
Antwoord 1, autoriteit 100%
Als u op zoek bent naar een manier om dit te bereiken zonder een externe bibliotheek te gebruiken, zal de volgende code u helpen.
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;
}
Je kunt de geretourneerde kaart openen met <map>.get("client_id")
, met de URL die in je vraag is gegeven, zou dit “SS” opleveren.
UPDATEURL-decodering toegevoegd
UPDATEOmdat dit antwoord nog steeds behoorlijk populair is, heb ik een verbeterde versie van de bovenstaande methode gemaakt, die meerdere parameters met dezelfde sleutel en ook parameters zonder waarde verwerkt.
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;
}
UPDATEJava8-versie
public Map<String, List<String>> splitQuery(URL url) {
if (Strings.isNullOrEmpty(url.getQuery())) {
return Collections.emptyMap();
}
return Arrays.stream(url.getQuery().split("&"))
.map(this::splitQueryParameter)
.collect(Collectors.groupingBy(SimpleImmutableEntry::getKey, LinkedHashMap::new, mapping(Map.Entry::getValue, toList())));
}
public SimpleImmutableEntry<String, String> splitQueryParameter(String it) {
final int idx = it.indexOf("=");
final String key = idx > 0 ? it.substring(0, idx) : it;
final String value = idx > 0 && it.length() > idx + 1 ? it.substring(idx + 1) : null;
return new SimpleImmutableEntry<>(
URLDecoder.decode(key, "UTF-8"),
URLDecoder.decode(value, "UTF-8")
);
}
De bovenstaande methode uitvoeren met de URL
https://stackoverflow.com?param1=value1¶m2=¶m3=value3¶m3
retourneert deze kaart:
{param1=["value1"], param2=[null], param3=["value3", null]}
Antwoord 2, autoriteit 90%
org. apache.http.client.utils.URLEncodedUtils
is een bekende bibliotheek die dit voor u kan doen
import org.apache.hc.client5.http.utils.URLEncodedUtils
String url = "http://www.example.com/something.html?one=1&two=2&three=3&three=3a";
List<NameValuePair> params = URLEncodedUtils.parse(new URI(url), Charset.forName("UTF-8"));
for (NameValuePair param : params) {
System.out.println(param.getName() + " : " + param.getValue());
}
Uitgangen
one : 1
two : 2
three : 3
three : 3a
Antwoord 3, autoriteit 35%
Als je Spring Framework gebruikt:
public static void main(String[] args) {
String uri = "http://my.test.com/test?param1=ab¶m2=cd¶m2=ef";
MultiValueMap<String, String> parameters =
UriComponentsBuilder.fromUriString(uri).build().getQueryParams();
List<String> param1 = parameters.get("param1");
List<String> param2 = parameters.get("param2");
System.out.println("param1: " + param1.get(0));
System.out.println("param2: " + param2.get(0) + "," + param2.get(1));
}
Je krijgt:
param1: ab
param2: cd,ef
Antwoord 4, autoriteit 14%
gebruik google Guava en doe het in 2 regels:
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);
}
}
waardoor je
{client_id=SS, response_type=code, scope=N_FULL, access_type=offline, redirect_uri=http://localhost/Callback}
Antwoord 5, autoriteit 11%
De kortste manier die ik heb gevonden is deze:
MultiValueMap<String, String> queryParams =
UriComponentsBuilder.fromUriString(url).build().getQueryParams();
UPDATE:UriComponentsBuilder
komt uit Spring. Hier de link.
Antwoord 6, autoriteit 6%
Voor Android, als je OkHttpgebruikt in je project. Hier kun je misschien naar kijken. Het is eenvoudig en nuttig.
final HttpUrl url = HttpUrl.parse(query);
if (url != null) {
final String target = url.queryParameter("target");
final String id = url.queryParameter("id");
}
Antwoord 7, autoriteit 5%
GEWONE Java 11
Gegeven de te analyseren URL:
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");
Deze oplossing verzamelt een lijst met paren:
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());
Deze oplossing daarentegen verzamelt een kaart (aangezien er in een url meer parameters kunnen zijn met dezelfde naam maar met verschillende waarden).
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 oplossingen moeten een hulpprogramma gebruiken om de parameters correct te decoderen.
private static String decode(final String encoded) {
return Optional.ofNullable(encoded)
.map(e -> URLDecoder.decode(e, StandardCharsets.UTF_8))
.orElse(null);
}
Antwoord 8, autoriteit 3%
Als je servlet doGet gebruikt, probeer dit dan
request.getParameterMap()
Retourneert een java.util.Map van de parameters van dit verzoek.
Retouren:
een onveranderlijke java.util.Map met parameternamen als sleutels en parameterwaarden als kaartwaarden. De toetsen in de parametermap zijn van het type String. De waarden in de parametermap zijn van het type String array.
Antwoord 9, autoriteit 3%
Op Android is er een Uri-klasse in pakket android.net. Merk op dat Urideel uitmaakt van android.net, terwijl URIdeel uitmaakt van java.net.
Uri-klasse heeft veel functies om sleutel-waardeparen uit een query te extraheren.
De volgende functie retourneert sleutel-waardeparen in de vorm van HashMap.
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
}
Antwoord 10, autoriteit 2%
Als je Java 8 gebruikt en bereid bent een paar herbruikbare methoden te schrijven, kun je dat in één regel doen.
private Map<String, List<String>> parse(final String query) {
return Arrays.asList(query.split("&")).stream().map(p -> p.split("=")).collect(Collectors.toMap(s -> decode(index(s, 0)), s -> Arrays.asList(decode(index(s, 1))), this::mergeLists));
}
private <T> List<T> mergeLists(final List<T> l1, final List<T> l2) {
List<T> list = new ArrayList<>();
list.addAll(l1);
list.addAll(l2);
return list;
}
private static <T> T index(final T[] array, final int index) {
return index >= array.length ? null : array[index];
}
private static String decode(final String encoded) {
try {
return encoded == null ? null : URLDecoder.decode(encoded, "UTF-8");
} catch(final UnsupportedEncodingException e) {
throw new RuntimeException("Impossible: UTF-8 is a required encoding", e);
}
}
Maar dat is een behoorlijk brute regel.
Antwoord 11, autoriteit 2%
Nettybiedt ook een mooie query-string-parser genaamd QueryStringDecoder
.
In één regel code kan het de URL in de vraag ontleden.
Ik vind het leuk omdat het niet nodig is om java.net.MalformedURLException
te vangen of te gooien.
In één regel:
Map<String, List<String>> parameters = new QueryStringDecoder(url).parameters();
Bekijk javadocs hier: https://netty. io/4.1/api/io/netty/handler/codec/http/QueryStringDecoder.html
Hier is een kort, op zichzelf staand, correct voorbeeld:
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 genereert
NAME VALUE
------------------------
client_id SS
response_type code
scope N_FULL
access_type offline
redirect_uri http://localhost/Callback
Antwoord 12
Met behulp van bovengenoemde opmerkingen en oplossingen sla ik alle queryparameters op met behulp van Map<String, Object> waar Objecten een string of Set<String> kunnen zijn. De oplossing wordt hieronder gegeven. Het wordt aanbevolen om een soort url-validator te gebruiken om de url eerst te valideren en vervolgens de methode convertQueryStringToMap aan te roepen.
private static final String DEFAULT_ENCODING_SCHEME = "UTF-8";
public static Map<String, Object> convertQueryStringToMap(String url) throws UnsupportedEncodingException, URISyntaxException {
List<NameValuePair> params = URLEncodedUtils.parse(new URI(url), DEFAULT_ENCODING_SCHEME);
Map<String, Object> queryStringMap = new HashMap<>();
for(NameValuePair param : params){
queryStringMap.put(param.getName(), handleMultiValuedQueryParam(queryStringMap, param.getName(), param.getValue()));
}
return queryStringMap;
}
private static Object handleMultiValuedQueryParam(Map responseMap, String key, String value) {
if (!responseMap.containsKey(key)) {
return value.contains(",") ? new HashSet<String>(Arrays.asList(value.split(","))) : value;
} else {
Set<String> queryValueSet = responseMap.get(key) instanceof Set ? (Set<String>) responseMap.get(key) : new HashSet<String>();
if (value.contains(",")) {
queryValueSet.addAll(Arrays.asList(value.split(",")));
} else {
queryValueSet.add(value);
}
return queryValueSet;
}
}
Antwoord 13
Ik heb een Kotlin-versie geprobeerd om te zien hoe dit het beste resultaat in Google is.
@Throws(UnsupportedEncodingException::class)
fun splitQuery(url: URL): Map<String, List<String>> {
val queryPairs = LinkedHashMap<String, ArrayList<String>>()
url.query.split("&".toRegex())
.dropLastWhile { it.isEmpty() }
.map { it.split('=') }
.map { it.getOrEmpty(0).decodeToUTF8() to it.getOrEmpty(1).decodeToUTF8() }
.forEach { (key, value) ->
if (!queryPairs.containsKey(key)) {
queryPairs[key] = arrayListOf(value)
} else {
if(!queryPairs[key]!!.contains(value)) {
queryPairs[key]!!.add(value)
}
}
}
return queryPairs
}
En de extensiemethoden
fun List<String>.getOrEmpty(index: Int) : String {
return getOrElse(index) {""}
}
fun String.decodeToUTF8(): String {
URLDecoder.decode(this, "UTF-8")
}
Antwoord 14
Een kant-en-klare oplossing voor het decoderen van URI-querygedeelte (incl. decodering en multiparameterwaarden)
Opmerkingen
Ik was niet blij met de code van @Pr0gr4mm3r in https://stackoverflow.com/a/13592567/1211082. De op Stream gebaseerde oplossing doet geen URLDecoding, de veranderlijke versie is onhandig.
Zo heb ik een oplossing uitgewerkt die
- Kan een URI-querygedeelte ontleden in een
Map<String, List<Optional<String>>>
- Kan meerdere waarden verwerkenvoor dezelfde parameternaam
- Kan parameters zonder waarde correct weergeven(
Optional.empty()
in plaats vannull
) - Decodeert parameternamenen waarden correctvia
URLdecode
- Is gebaseerd op Java 8-streams
- Is direct bruikbaar (zie code inclusief import hieronder)
- Maakt een juiste foutafhandeling mogelijk (hier door een gecontroleerde uitzondering
UnsupportedEncodingException
in een runtime-uitzonderingRuntimeUnsupportedEncodingException
te veranderen die interactie met stream mogelijk maakt. (De reguliere functie verpakken in functies die gecontroleerde uitzonderingen weggooien) is lastig. En ScalaTry
is niet beschikbaar in de standaard Java-taal.)
Java-code
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import static java.util.stream.Collectors.*;
public class URIParameterDecode {
/**
* Decode parameters in query part of a URI into a map from parameter name to its parameter values.
* For parameters that occur multiple times each value is collected.
* Proper decoding of the parameters is performed.
*
* Example
* <pre>a=1&b=2&c=&a=4</pre>
* is converted into
* <pre>{a=[Optional[1], Optional[4]], b=[Optional[2]], c=[Optional.empty]}</pre>
* @param query the query part of an URI
* @return map of parameters names into a list of their values.
*
*/
public static Map<String, List<Optional<String>>> splitQuery(String query) {
if (query == null || query.isEmpty()) {
return Collections.emptyMap();
}
return Arrays.stream(query.split("&"))
.map(p -> splitQueryParameter(p))
.collect(groupingBy(e -> e.get0(), // group by parameter name
mapping(e -> e.get1(), toList())));// keep parameter values and assemble into list
}
public static Pair<String, Optional<String>> splitQueryParameter(String parameter) {
final String enc = "UTF-8";
List<String> keyValue = Arrays.stream(parameter.split("="))
.map(e -> {
try {
return URLDecoder.decode(e, enc);
} catch (UnsupportedEncodingException ex) {
throw new RuntimeUnsupportedEncodingException(ex);
}
}).collect(toList());
if (keyValue.size() == 2) {
return new Pair(keyValue.get(0), Optional.of(keyValue.get(1)));
} else {
return new Pair(keyValue.get(0), Optional.empty());
}
}
/** Runtime exception (instead of checked exception) to denote unsupported enconding */
public static class RuntimeUnsupportedEncodingException extends RuntimeException {
public RuntimeUnsupportedEncodingException(Throwable cause) {
super(cause);
}
}
/**
* A simple pair of two elements
* @param <U> first element
* @param <V> second element
*/
public static class Pair<U, V> {
U a;
V b;
public Pair(U u, V v) {
this.a = u;
this.b = v;
}
public U get0() {
return a;
}
public V get1() {
return b;
}
}
}
Scala-code
… en voor de volledigheid kan ik het niet laten om in Scala de oplossing te bieden die overheerst door beknoptheid en schoonheid
import java.net.URLDecoder
object Decode {
def main(args: Array[String]): Unit = {
val input = "a=1&b=2&c=&a=4";
println(separate(input))
}
def separate(input: String) : Map[String, List[Option[String]]] = {
case class Parameter(key: String, value: Option[String])
def separateParameter(parameter: String) : Parameter =
parameter.split("=")
.map(e => URLDecoder.decode(e, "UTF-8")) match {
case Array(key, value) => Parameter(key, Some(value))
case Array(key) => Parameter(key, None)
}
input.split("&").toList
.map(p => separateParameter(p))
.groupBy(p => p.key)
.mapValues(vs => vs.map(p => p.value))
}
}
Antwoord 15
Antwoord van Kotlin met initiële referentie van https://stackoverflow.com/a/51024552/3286489, maar met verbeterde versie door codes op te ruimen en 2 versies ervan te bieden, en onveranderlijke verzamelingsbewerkingen te gebruiken
Gebruik java.net.URI
om de query uit te pakken. Gebruik dan de onderstaande uitbreidingsfuncties
- Ervan uitgaande dat u alleen de laatste waarde van de zoekopdracht wilt, d.w.z.
page2&page3
krijgt{page=3}
, gebruik dan de onderstaande extensiefunctie
fun URI.getQueryMap(): Map<String, String> {
if (query == null) return emptyMap()
return query.split("&")
.mapNotNull { element -> element.split("=")
.takeIf { it.size == 2 && it.none { it.isBlank() } } }
.associateBy({ it[0].decodeUTF8() }, { it[1].decodeUTF8() })
}
private fun String.decodeUTF8() = URLDecoder.decode(this, "UTF-8") // decode page=%22ABC%22 to page="ABC"
- Ervan uitgaande dat u een lijst met alle waarden voor de zoekopdracht wilt, d.w.z.
page2&page3
krijgt{page=[2, 3]}
fun URI.getQueryMapList(): Map<String, List<String>> {
if (query == null) return emptyMap()
return query.split("&")
.distinct()
.mapNotNull { element -> element.split("=")
.takeIf { it.size == 2 && it.none { it.isBlank() } } }
.groupBy({ it[0].decodeUTF8() }, { it[1].decodeUTF8() })
}
private fun String.decodeUTF8() = URLDecoder.decode(this, "UTF-8") // decode page=%22ABC%22 to page="ABC"
De manier om het te gebruiken zoals hieronder
val uri = URI("schema://host/path/?page=&page=2&page=2&page=3")
println(uri.getQueryMapList()) // Result is {page=[2, 3]}
println(uri.getQueryMap()) // Result is {page=3}
Antwoord 16
Er zijn tal van antwoorden die geschikt zijn voor uw zoekopdracht, zoals u hebt aangegeven wanneer deze definities van één enkele parameter heeft. In sommige toepassingen kan het handig zijn om een paar extra randgevallen van queryparameters af te handelen, zoals:
- lijst met parameterwaarden zoals
param1¶m1=value¶m1=
wat betekent datparam1
is ingesteld opList.of("", "value", "")
- ongeldige permutaties zoals
querypath?&=&&=noparamname&
. - gebruik een lege tekenreeks die niet null is in kaarten
a=
betekent dat “a”List.of("")
is om overeen te komen met de verwerking van webservlet’s
Dit gebruikt een Stream met filters en groupingBy om te verzamelen naar Map<String, List<String>>
:
public static Map<String, List<String>> getParameterValues(URL url) {
return Arrays.stream(url.getQuery().split("&"))
.map(s -> s.split("="))
// filter out empty parameter names (as in Tomcat) "?&=&&=value&":
.filter(arr -> arr.length > 0 && arr[0].length() > 0)
.collect(Collectors.groupingBy(arr -> URLDecoder.decode(arr[0], StandardCharsets.UTF_8),
// drop this line for not-name definition order Map:
LinkedHashMap::new,
Collectors.mapping(arr -> arr.length < 2 ? "" : URLDecoder.decode(arr[1], StandardCharsets.UTF_8), Collectors.toList())));
}
Antwoord 17
Als je Spring gebruikt, voeg dan een argument van het type @RequestParam Map<String,String>
toe aan je controllermethode, en Spring zal de kaart voor je samenstellen!
Antwoord 18
Gewoon een update naar de Java 8-versie
public Map<String, List<String>> splitQuery(URL url) {
if (Strings.isNullOrEmpty(url.getQuery())) {
return Collections.emptyMap();
}
return Arrays.stream(url.getQuery().split("&"))
.map(this::splitQueryParameter)
.collect(Collectors.groupingBy(SimpleImmutableEntry::getKey, LinkedHashMap::new, **Collectors**.mapping(Map.Entry::getValue, **Collectors**.toList())));
}
mapping- en toList()-methoden moeten worden gebruikt met Collectors, wat niet werd genoemd in het bovenste antwoord. Anders zou het een compilatiefout in IDE veroorzaken
Antwoord 19
Ik reageer hier omdat dit een populaire thread is. Dit is een schone oplossing in Kotlin die de aanbevolen api UrlQuerySanitizer
gebruikt. Zie de officiële documentatie. Ik heb een stringbuilder toegevoegd om de parameters samen te voegen en weer te geven.
var myURL: String? = null
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")
}
Antwoord 20
Hier is mijn oplossing met reduceen Optioneel:
private Optional<SimpleImmutableEntry<String, String>> splitKeyValue(String text) {
String[] v = text.split("=");
if (v.length == 1 || v.length == 2) {
String key = URLDecoder.decode(v[0], StandardCharsets.UTF_8);
String value = v.length == 2 ? URLDecoder.decode(v[1], StandardCharsets.UTF_8) : null;
return Optional.of(new SimpleImmutableEntry<String, String>(key, value));
} else
return Optional.empty();
}
private HashMap<String, String> parseQuery(URI uri) {
HashMap<String, String> params = Arrays.stream(uri.getQuery()
.split("&"))
.map(this::splitKeyValue)
.filter(Optional::isPresent)
.map(Optional::get)
.reduce(
// initial value
new HashMap<String, String>(),
// accumulator
(map, kv) -> {
map.put(kv.getKey(), kv.getValue());
return map;
},
// combiner
(a, b) -> {
a.putAll(b);
return a;
});
return params;
}
- Ik negeer dubbele parameters (ik neem de laatste).
- Ik gebruik
Optional<SimpleImmutableEntry<String, String>>
om later rommel te negeren - De reductie begint met een lege kaart en vult deze vervolgens op elke SimpleImmutableEntry
Als je het vraagt, reducevereist deze rare combinator in de laatste parameter, die alleen wordt gebruikt in parallelle streams. Het doel is om twee tussenresultaten samen te voegen (hier HashMap).
Antwoord 21
Als je toevallig cxf-core op het klassenpad hebt staan en je weet dat je geen herhaalde queryparameters hebt, wil je misschien UrlUtils.parseQueryString.
Antwoord 22
Het Eclipse Jersey REST-frameworkondersteunt dit via UriComponent
. Voorbeeld:
import org.glassfish.jersey.uri.UriComponent;
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";
MultivaluedMap<String, String> params = UriComponent.decodeQuery(URI.create(uri), true);
for (String key : params.keySet()) {
System.out.println(key + ": " + params.getFirst(key));
}
Antwoord 23
Als je alleen de parameters na de URL van een String wilt. Dan werkt de volgende code. Ik ga uit van de simpele URL. Ik bedoel geen hard en snel controleren en decoderen. Zoals in een van mijn testcases kreeg ik de URL en ik weet dat ik alleen de waarde van de parameters nodig heb. De url was simpel. Geen codering en decodering nodig.
String location = "https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback";
String location1 = "https://stackoverflow.com?param1=value1¶m2=value2¶m3=value3";
String location2 = "https://stackoverflow.com?param1=value1¶m2=¶m3=value3¶m3";
Map<String, String> paramsMap = Stream.of(location)
.filter(l -> l.indexOf("?") != -1)
.map(l -> l.substring(l.indexOf("?") + 1, l.length()))
.flatMap(q -> Pattern.compile("&").splitAsStream(q))
.map(s -> s.split("="))
.filter(a -> a.length == 2)
.collect(Collectors.toMap(
a -> a[0],
a -> a[1],
(existing, replacement) -> existing + ", " + replacement,
LinkedHashMap::new
));
System.out.println(paramsMap);
bedankt