java 如何将查询参数附加到现有URL?

iyfamqjs  于 2023-01-01  发布在  Java
关注(0)|答案(8)|浏览(174)

我想把键值对作为查询参数附加到一个现有的URL上。虽然我可以通过检查URL是否有查询部分或片段部分的存在来完成这个操作,并通过跳过一堆if子句来完成附加,但我想知道如果通过Apache Commons库或类似的东西来完成这个操作,是否有干净的方法。
http://example.com应该是http://example.com?name=John
http://example.com#fragment应该是http://example.com?name=John#fragment
http://example.com?email=john.doe@email.com应该是http://example.com?email=john.doe@email.com&name=John
http://example.com?email=john.doe@email.com#fragment应该是http://example.com?email=john.doe@email.com&name=John#fragment
我已经运行过这个场景很多次了,我想这样做,而不以任何方式打破URL。

wr98u20j

wr98u20j1#

有很多库可以帮助你构建URI(不要重复发明轮子),这里有三个库可以帮助你开始:

Java EE 7

import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();

org.apache. http组件:http客户端:4.5.2

import org.apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();

网站名称:spring-web:4.2.5.版本

import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();

另请参阅:GIST > URI Builder Tests

wlwcrazw

wlwcrazw2#

这可以通过使用java.net.URI类构造一个新示例来完成,该示例使用现有示例的部分,这应该确保它符合URI语法。
查询部分将为空或现有字符串,因此您可以决定使用&追加另一个参数或开始新的查询。

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;  
        }

        return new URI(oldUri.getScheme(), oldUri.getAuthority(),
                oldUri.getPath(), newQuery, oldUri.getFragment());
    }

    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"));
    }
}

较短的备选方案

public static URI appendUri(String uri, String appendQuery) throws URISyntaxException {
    URI oldUri = new URI(uri);
    return new URI(oldUri.getScheme(), oldUri.getAuthority(), oldUri.getPath(),
            oldUri.getQuery() == null ? appendQuery : oldUri.getQuery() + "&" + appendQuery, oldUri.getFragment());
}

产出

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
luaexgnf

luaexgnf3#

对于Android,请用途:https://developer.android.com/reference/android/net/Uri#buildUpon()

URI oldUri = new URI(uri);
Uri.Builder builder = oldUri.buildUpon();
 builder.appendQueryParameter("newParameter", "dummyvalue");
 Uri newUri =  builder.build();
5lwkijsr

5lwkijsr4#

使用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());
8mmmxcuj

8mmmxcuj5#

我建议改进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();
}
zd287kbt

zd287kbt6#

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()
    }
cyvaqqii

cyvaqqii7#

使用此函数将新参数附加到现有URI

private Uri appendUriParameter(Uri uri, String key, String newValue) {
        final Set<String> params = uri.getQueryParameterNames();
        final Uri.Builder newUri = uri.buildUpon().clearQuery();
        for (String param : params) {
          newUri.appendQueryParameter(param, uri.getQueryParameter(param));
        }
        newUri.appendQueryParameter(key, newValue);
    
        return newUri.build();
      }
nxowjjhe

nxowjjhe8#

更新亚当的答案,同时考虑到tryp的答案。不必在循环中示例化字符串。

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;
}

相关问题