Ich möchte ein Schlüssel-Wert-Paar als Abfrageparameter an eine vorhandene URL anhängen. Ich könnte dies zwar tun, indem ich nach dem Vorhandensein von URLs und Abfrageteilen frage, ob die URL einen Abfrageteil oder einen Fragmentteil hat, und zwar durch ein Bündel von If-Klauseln, aber ich habe mich gefragt, ob es einen sauberen Weg gibt, wenn dies durch den Apache geschieht Commons-Bibliotheken oder etwas Äquivalentes.
http://example.com
wäre http://example.com?name=John
http://example.com#fragment
wäre http://example.com?name=John#fragment
http://[email protected]
wäre http://[email protected]&name=John
http://[email protected]#fragment
wäre http://[email protected]&name=John#fragment
Ich habe dieses Szenario schon oft ausgeführt und möchte dies gerne tun, ohne die URL in irgendeiner Weise zu beschädigen.
Dies kann durch die Verwendung der Klasse Java.net.URI zum Erstellen einer neuen Instanz unter Verwendung der Teile aus einer vorhandenen Instanz erfolgen. Dies sollte sicherstellen, dass sie der URI-Syntax entspricht.
Der Abfrageteil ist entweder null oder eine vorhandene Zeichenfolge. Sie können also einen anderen Parameter mit & anhängen oder eine neue Abfrage starten.
public class StackOverflow26177749 {
public static URI appendUri(String uri, String appendQuery) throws URISyntaxException {
URI oldUri = new URI(uri);
String newQuery = oldUri.getQuery();
if (newQuery == null) {
newQuery = appendQuery;
} else {
newQuery += "&" + appendQuery;
}
URI newUri = new URI(oldUri.getScheme(), oldUri.getAuthority(),
oldUri.getPath(), newQuery, oldUri.getFragment());
return newUri;
}
public static void main(String[] args) throws Exception {
System.out.println(appendUri("http://example.com", "name=John"));
System.out.println(appendUri("http://example.com#fragment", "name=John"));
System.out.println(appendUri("http://[email protected]", "name=John"));
System.out.println(appendUri("http://[email protected]#fragment", "name=John"));
}
}
Ausgabe
http://example.com?name=John
http://example.com?name=John#fragment
http://[email protected]&name=John
http://[email protected]&name=John#fragment
Es gibt viele Bibliotheken, die Ihnen beim URI-Aufbau helfen können (das Rad nicht neu erfinden). Hier sind drei, um den Einstieg zu erleichtern:
import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();
import org.Apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();
import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();
Siehe auch:Gist> URI Builder-Tests
Verwenden Sie die URI
-Klasse.
Erstellen Sie eine neue URI
mit Ihrer vorhandenen String
, um sie in Teile aufzuteilen, und instanziieren Sie eine andere, um die geänderte URL zusammenzusetzen:
URI u = new URI("http://[email protected]&name=John#fragment");
// Modify the query: append your new parameter
StringBuilder sb = new StringBuilder(u.getQuery() == null ? "" : u.getQuery());
if (sb.length() > 0)
sb.append('&');
sb.append(URLEncoder.encode("paramName", "UTF-8"));
sb.append('=');
sb.append(URLEncoder.encode("paramValue", "UTF-8"));
// Build the new url with the modified query:
URI u2 = new URI(u.getScheme(), u.getAuthority(), u.getPath(),
sb.toString(), u.getFragment());
Ich schlage eine Verbesserung der Antwort von Adam vor, die HashMap als Parameter akzeptiert
/**
* Append parameters to given url
* @param url
* @param parameters
* @return new String url with given parameters
* @throws URISyntaxException
*/
public static String appendToUrl(String url, HashMap<String, String> parameters) throws URISyntaxException
{
URI uri = new URI(url);
String query = uri.getQuery();
StringBuilder builder = new StringBuilder();
if (query != null)
builder.append(query);
for (Map.Entry<String, String> entry: parameters.entrySet())
{
String keyValueParam = entry.getKey() + "=" + entry.getValue();
if (!builder.toString().isEmpty())
builder.append("&");
builder.append(keyValueParam);
}
URI newUri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), builder.toString(), uri.getFragment());
return newUri.toString();
}
Kotlin & clean, so dass Sie nicht vor der Codeüberprüfung umgestalten müssen:
private fun addQueryParameters(url: String?): String? {
val uri = URI(url)
val queryParams = StringBuilder(uri.query.orEmpty())
if (queryParams.isNotEmpty())
queryParams.append('&')
queryParams.append(URLEncoder.encode("$QUERY_PARAM=$param", Xml.Encoding.UTF_8.name))
return URI(uri.scheme, uri.authority, uri.path, queryParams.toString(), uri.fragment).toString()
}