Java 如何将查询参数附加到现有 URL?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26177749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I append a query parameter to an existing URL?
提问by Mridang Agarwalla
I'd like to append key-value pair as a query parameter to an existing URL. While I could do this by checking for the existence of whether the URL has a query part or a fragment part and doing the append by jumping though a bunch of if-clauses but I was wondering if there was clean way if doing this through the Apache Commons libraries or something equivalent.
我想将键值对作为查询参数附加到现有 URL。虽然我可以通过检查 URL 是否有查询部分或片段部分并通过跳过一堆 if 子句来执行追加来做到这一点,但我想知道如果通过 Apache 执行此操作是否有干净的方法公共图书馆或类似的东西。
http://example.com
would be http://example.com?name=John
http://example.com
将是 http://example.com?name=John
http://example.com#fragment
would be http://example.com?name=John#fragment
http://example.com#fragment
将是 http://example.com?name=John#fragment
http://[email protected]
would be http://[email protected]&name=John
http://[email protected]
将是 http://[email protected]&name=John
http://[email protected]#fragment
would be http://[email protected]&name=John#fragment
http://[email protected]#fragment
将是 http://[email protected]&name=John#fragment
I've run this scenario many times before and I'd like to do this without breaking the URL in any way.
我之前已经多次运行这个场景,我希望在不以任何方式破坏 URL 的情况下执行此操作。
采纳答案by Adam
This can be done by using the java.net.URIclass to construct a new instance using the parts from an existing one, this should ensure it conforms to URI syntax.
这可以通过使用java.net.URI类使用现有部分的部分构造一个新实例来完成,这应确保它符合 URI 语法。
The query part will either be null or an existing string, so you can decide to append another parameter with & or start a new query.
查询部分将为空或现有字符串,因此您可以决定使用 & 附加另一个参数或开始新查询。
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"));
}
}
Output
输出
http://example.com?name=John
http://example.com?name=John#fragment
http://[email protected]&name=John
http://[email protected]&name=John#fragment
回答by icza
Use the URI
class.
使用URI
类。
Create a new URI
with your existing String
to "break it up" to parts, and instantiate another one to assemble the modified url:
URI
使用现有的创建一个新的String
“分解”为部分,并实例化另一个以组装修改后的 url:
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());
回答by Nick Grealy
There are plenty of libraries that can help you with URI building (don't reinvent the wheel). Here are three to get you started:
有很多库可以帮助您构建 URI(不要重新发明轮子)。这里有三个让你开始:
Java EE 7
Java EE 7
import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();
org.apache.httpcomponents:httpclient:4.5.2
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
org.springframework:spring-web:4.2.5.RELEASE
import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();
See also:GIST > URI Builder Tests
回答by tryp
I suggest an improvement of the Adam's answer accepting HashMap as parameter
我建议改进 Adam 的答案,接受 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<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();
}
回答by Andrii Kovalchuk
Kotlin & clean, so you don't have to refactor before code review:
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()
}
回答by Ananth George
An update to Adam's answer considering tryp's answer too. Don't have to instantiate a String in the loop.
考虑到 tryp 的回答,对 Adam 的回答进行了更新。不必在循环中实例化 String。
public static URI appendUri(String uri, Map<String, String> parameters) throws URISyntaxException {
URI oldUri = new URI(uri);
StringBuilder queries = new StringBuilder();
for(Map.Entry<String, String> query: parameters.entrySet()) {
queries.append( "&" + query.getKey()+"="+query.getValue());
}
String newQuery = oldUri.getQuery();
if (newQuery == null) {
newQuery = queries.substring(1);
} else {
newQuery += queries.toString();
}
URI newUri = new URI(oldUri.getScheme(), oldUri.getAuthority(),
oldUri.getPath(), newQuery, oldUri.getFragment());
return newUri;
}