89

MapをURLに適したクエリ文字列に変換できるユーティリティクラス/ライブラリを知っていますか?

例:

私は地図を持っています:

"param1"=12,
"param2"="cat"

私は手に入れたい:

param1=12&param2=cat

最終出力

relativeUrl+param1=12&param2=cat
4

18 に答える 18

71

既製品で最も堅牢なものは、Apache Http Compoments (HttpClient 4.0)のURLEncodedUtilsクラスです。

メソッドURLEncodedUtils.format()は必要なものです。

マップを使用しないため、次のようにパラメーター名を重複させることができます。

  a=1&a=2&b=3

この種のパラメーター名の使用をお勧めするわけではありません。

于 2010-05-11T12:00:27.503 に答える
45

これは私がすぐに書いたものです。きっと改善できると思います。

import java.util.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class MapQuery {
    static String urlEncodeUTF8(String s) {
        try {
            return URLEncoder.encode(s, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new UnsupportedOperationException(e);
        }
    }
    static String urlEncodeUTF8(Map<?,?> map) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<?,?> entry : map.entrySet()) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(String.format("%s=%s",
                urlEncodeUTF8(entry.getKey().toString()),
                urlEncodeUTF8(entry.getValue().toString())
            ));
        }
        return sb.toString();       
    }
    public static void main(String[] args) {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("p1", 12);
        map.put("p2", "cat");
        map.put("p3", "a & b");         
        System.out.println(urlEncodeUTF8(map));
        // prints "p3=a+%26+b&p2=cat&p1=12"
    }
}
于 2010-05-11T11:09:08.780 に答える
42

Java 8 と polygenelubricants のソリューションを使用してスムーズなソリューションを見つけました。

parameters.entrySet().stream()
    .map(p -> urlEncodeUTF8(p.getKey()) + "=" + urlEncodeUTF8(p.getValue()))
    .reduce((p1, p2) -> p1 + "&" + p2)
    .orElse("");
于 2015-03-23T14:40:31.647 に答える
23

Spring Utilには、もっと良い方法があります..、

import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("key", key);
params.add("storeId", storeId);
params.add("orderId", orderId);
UriComponents uriComponents =     UriComponentsBuilder.fromHttpUrl("http://spsenthil.com/order").queryParams(params).build();
ListenableFuture<ResponseEntity<String>> responseFuture =     restTemplate.getForEntity(uriComponents.toUriString(), String.class);
于 2014-08-14T02:42:35.267 に答える
19

2016 年 6 月の更新

parse非常に一般的な問題 - 優れたライブラリと操作の両方の確かな使用例 - に対して、あまりにも多くの SOF 回答を見て、古い回答や不十分な回答を見て、回答を追加することを強いられたと感じましたformat

org.apache.httpcomponents.httpclientライブラリを使用します。ライブラリには、このorg.apache.http.client.utils.URLEncodedUtilsクラス ユーティリティが含まれています。

たとえば、Maven からこの依存関係を簡単にダウンロードできます。

 <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5</version>
 </dependency>

私の目的では、parse(クエリ文字列から名前と値のペアへの読み取り) とformat(名前と値のペアからクエリ文字列への読み取り) クエリ文字列のみが必要でした。ただし、URI で同じことを行う同等のものがあります (以下のコメントアウトされた行を参照してください)。

// 必要なインポート

import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

// コードスニペット

public static void parseAndFormatExample() throws UnsupportedEncodingException {
        final String queryString = "nonce=12345&redirectCallbackUrl=http://www.bbc.co.uk";
        System.out.println(queryString);
        // => nonce=12345&redirectCallbackUrl=http://www.bbc.co.uk

        final List<NameValuePair> params =
                URLEncodedUtils.parse(queryString, StandardCharsets.UTF_8);
        // List<NameValuePair> params = URLEncodedUtils.parse(new URI(url), "UTF-8");

        for (final NameValuePair param : params) {
            System.out.println(param.getName() + " : " + param.getValue());
            // => nonce : 12345
            // => redirectCallbackUrl : http://www.bbc.co.uk
        }

        final String newQueryStringEncoded =
                URLEncodedUtils.format(params, StandardCharsets.UTF_8);


        // decode when printing to screen
        final String newQueryStringDecoded =
                URLDecoder.decode(newQueryStringEncoded, StandardCharsets.UTF_8.toString());
        System.out.println(newQueryStringDecoded);
        // => nonce=12345&redirectCallbackUrl=http://www.bbc.co.uk
    }

このライブラリは私が必要としていたことを正確に実行し、ハッキングされたカスタム コードを置き換えることができました。

于 2016-06-10T08:55:38.300 に答える
10

実際に完全なURIを構築したい場合は、Apache Http Compoments(HttpClient 4)のURIBuilderを試してください。

これは実際には質問に答えませんが、この質問を見つけたときに持っていた質問には答えました。

于 2012-11-08T13:30:41.707 に答える
6

これは、Java 8 と を使用して実装したソリューションですorg.apache.http.client.URLEncodedUtils。マップのエントリをリストにマップし、BasicNameValuePairApache を使用してURLEncodedUtilsそれをクエリ文字列に変換します。

List<BasicNameValuePair> nameValuePairs = params.entrySet().stream()
   .map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
   .collect(Collectors.toList());

URLEncodedUtils.format(nameValuePairs, Charset.forName("UTF-8"));
于 2015-05-14T16:20:41.883 に答える
4

EntrySet とストリームの使用:

map
  .entrySet()
  .stream()
  .map(e -> e.getKey() + "=" + e.getValue())
  .collect(Collectors.joining("&"));
于 2019-06-19T13:25:17.060 に答える
1

@eclipseの答えを少し改善するには:Javalandでは、リクエストパラメーターマップは通常、 a Map<String, String[]>、 aMap<String, List<String>>またはおそらく何らかの種類のものとして表されMultiValueMap<String, String>ます。いずれにせよ、通常、パラメーターは複数の値を持つことができます。したがって、Java 8 ソリューションは次のようなものになります。

public String getQueryString(HttpServletRequest request, String encoding) {
    Map<String, String[]> parameters = request.getParameterMap();

    return parameters.entrySet().stream()
            .flatMap(entry -> encodeMultiParameter(entry.getKey(), entry.getValue(), encoding))
            .reduce((param1, param2) -> param1 + "&" + param2)
            .orElse("");
}

private Stream<String> encodeMultiParameter(String key, String[] values, String encoding) {
    return Stream.of(values).map(value -> encodeSingleParameter(key, value, encoding));
}

private String encodeSingleParameter(String key, String value, String encoding) {
    return urlEncode(key, encoding) + "=" + urlEncode(value, encoding);
}

private String urlEncode(String value, String encoding) {
    try {
        return URLEncoder.encode(value, encoding);
    } catch (UnsupportedEncodingException e) {
        throw new IllegalArgumentException("Cannot url encode " + value, e);
    }
}
于 2016-03-06T19:49:42.843 に答える