How to convert map to url query string?

前端 未结 17 1494
盖世英雄少女心
盖世英雄少女心 2020-11-27 13:39

Do you know of any utility class/library, that can convert Map into URL-friendly query string?

Example:

I have a map:

\"param1\"=12,
\"param2         


        
相关标签:
17条回答
  • 2020-11-27 14:32

    You can use a Stream for this, but instead of appending query parameters myself I'd use a Uri.Builder. For example:

    final Map<String, String> map = new HashMap<>();
    map.put("param1", "cat");
    map.put("param2", "12");
    
    final Uri uri = 
        map.entrySet().stream().collect(
            () -> Uri.parse("relativeUrl").buildUpon(),
            (builder, e) -> builder.appendQueryParameter(e.getKey(), e.getValue()),
            (b1, b2) -> { throw new UnsupportedOperationException(); }
        ).build();
    
    //Or, if you consider it more readable...
    final Uri.Builder builder = Uri.parse("relativeUrl").buildUpon();
    map.entrySet().forEach(e -> builder.appendQueryParameter(e.getKey(), e.getValue())
    final Uri uri = builder.build();
    
    //...    
    
    assertEquals(Uri.parse("relativeUrl?param1=cat&param2=12"), uri);
    
    0 讨论(0)
  • 2020-11-27 14:33

    Here's something that I quickly wrote; I'm sure it can be improved upon.

    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"
        }
    }
    
    0 讨论(0)
  • 2020-11-27 14:34

    I think this is better for memory usage and performance, and I want to send just the property name when the value is null.

    public static String toUrlEncode(Map<String, Object> map) {
        StringBuilder sb = new StringBuilder();
        map.entrySet().stream()
                .forEach(entry
                        -> (entry.getValue() == null
                        ? sb.append(entry.getKey())
                        : sb.append(entry.getKey())
                                .append('=')
                                .append(URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8)))
                        .append('&')
                );
        sb.delete(sb.length() - 1, sb.length());
        return sb.toString();
    }
    
    0 讨论(0)
  • 2020-11-27 14:35

    This is the solution I implemented, using Java 8 and org.apache.http.client.URLEncodedUtils. It maps the entries of the map into a list of BasicNameValuePair and then uses Apache's URLEncodedUtils to turn that into a query string.

    List<BasicNameValuePair> nameValuePairs = params.entrySet().stream()
       .map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
       .collect(Collectors.toList());
    
    URLEncodedUtils.format(nameValuePairs, Charset.forName("UTF-8"));
    
    0 讨论(0)
  • 2020-11-27 14:36

    I found a smooth solution using java 8 and polygenelubricants' solution.

    parameters.entrySet().stream()
        .map(p -> urlEncodeUTF8(p.getKey()) + "=" + urlEncodeUTF8(p.getValue()))
        .reduce((p1, p2) -> p1 + "&" + p2)
        .orElse("");
    
    0 讨论(0)
提交回复
热议问题