java-如何将查询参数附加到现有URL?
我想将键值对作为查询参数附加到现有URL。 虽然我可以通过检查URL是否存在查询部分还是片段部分并通过跳过一堆if子句来执行追加来做到这一点,但是我想知道是否有通过Apache进行清理的干净方法 公共图书馆或类似的东西。
http://example.com?email=john.doe@email.com#fragment将是http://example.com?email=john.doe@email.com&name=John#fragment
http://example.com?email=john.doe@email.com#fragment would be http://example.com?email=john.doe@email.com&name=John#fragment
http://example.com?email=john.doe@email.com#fragment would be http://example.com?email=john.doe@email.com&name=John#fragment
http://example.com?email=john.doe@email.com#fragment would be http://example.com?email=john.doe@email.com&name=John#fragment
我之前已经运行过多次这种情况,并且我希望做到这一点而不会以任何方式破坏URL。
Mridang Agarwalla asked 2020-07-05T07:56:01Z
5个解决方案
127 votes
有很多可以帮助您进行URI构建的库(请不要重新发明轮子)。 这是三个让您入门的方法:
Java EE 7
import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();
org.apache.httpcomponents:httpclient:4.5.2
import org.apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();
org.springframework:spring-web:4.2.5.RELEASE
import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();
另请参阅:GIST> URI构建器测试
Nick Grealy answered 2020-07-05T07:57:03Z
47 votes
这可以通过使用java.net.URI类使用现有实例中的部分构造一个新实例来完成,这应确保它符合URI语法。
查询部分将为null或现有字符串,因此您可以决定用&附加另一个参数或开始新查询。
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://example.com?email=john.doe@email.com", "name=John"));
System.out.println(appendUri("http://example.com?email=john.doe@email.com#fragment", "name=John"));
}
}
输出量
http://example.com?name=John
http://example.com?name=John#fragment
http://example.com?email=john.doe@email.com&name=John
http://example.com?email=john.doe@email.com&name=John#fragment
Adam answered 2020-07-05T07:56:26Z
5 votes
使用URI类。
使用现有的String创建一个新的URI,以将其“分解”为多个部分,并实例化另一个以组装修改后的URL:
URI u = new URI("http://example.com?email=john@email.com&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());
icza answered 2020-07-05T07:57:28Z
1 votes
我建议对接受HashMap作为参数的亚当答案有所改进
/**
* 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 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 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();
}
tryp answered 2020-07-05T07:57:48Z
0 votes
Kotlin&clean,因此您无需在代码审查之前进行重构:
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()
}
Андрій Ковальчук answered 2020-07-05T07:58:09Z