PHP'nin http_build_query fonksiyonu herhangi Java eşdeğer var mı?

5 Cevap java

Benim verilerle bir harita var ve sadece ben PHP http_build_query yaptığınız gibi, onunla bir sorgu dizesi oluşturmak istiyorum. Ben bir şey unutuyorum eğer bu kod iyi bunun uygulanması veya olup olmadığından emin değilim?

public String toQueryString(Map<?, ?> data) throws UnsupportedEncodingException {
    StringBuffer queryString = new StringBuffer();

    for (Entry<?, ?> pair : data.entrySet()) {
        queryString.append ( URLEncoder.encode ( (String) pair.getKey (), "UTF-8" ) + "=" );
        queryString.append ( URLEncoder.encode ( (String) pair.getValue (), "UTF-8" ) + "&" );
    }

    if (queryString.length () > 0) {
        queryString.deleteCharAt ( queryString.length () - 1 );
    }

	return queryString.toString ();
}

5 Cevap

QueryStringBuilder sınıfının ve onun bakmak test class:

private String httpBuildQuery(Map<String, String> data)
        throws UnsupportedEncodingException {
    QueryStringBuilder builder = new QueryStringBuilder();
    for (Entry<String, String> pair : data.entrySet()) {
        builder.addQueryParameter(pair.getKey(), pair.getValue());
    }
    return builder.encode("UTF-8");
}

Muhtemelen (muhtemelen en iyi seçenek olsa bile) UTF-8 zorlamadan önce istemci tarafından desteklenen kodlamaları için "Accept" isteği başlığını kontrol etmek isterdim.

Bu uyarılar ile, OK Tipler:

  • parametreyi Map<String, String> yerine String anahtarı ve değeri döküm yapmak.
  • kodlanmış kodlama şüpheli görünüyor. UTF-8 değil, bir, bu HTTP isteği başlığında tanımlanan kodlama maç var verilmiştir. Yani kod yapmaları emin olmalıdır - en azından sabit bir yerde olarak tanımlamak ve hem burada hem de istek kodlama ayarlanmış yerde olduğunu bakın.

Edit: Ben kodlama hakkında yanlış olduğu görünüyor; HTTP GET parametreleri bir kodlama başlığına tabi değildir, ve geleneksel olarak tüm iyi tanımlanmış bir kodlama yoktu. RFC 3988 UTF-8 zorunlu gibi görünüyor, ancak sunucu üzerinde sıkı bir kontrol var ve bu gerçekten de UTF-8 kullanır emin sürece, ben kullanmak istiyorum böylece, benim için oldukça kırılgan sesler 7bit ASCII aralığında olmayan herhangi bir veri POST istekleri.

PHP http_build_query fonksiyon gerçek güç ilişkisel dizi olsun ve URL dizesine çevirmek için yeteneğidir. Aşağıdaki kod benzer bir şey yapmak ve bu url params iç içe Haritasına ve Collections.With Array için bu bir destek de eklenebilir bazı çalışmalar şunlardır çok düzey Map olarak inşa edilmesini sağlar.

Deney yöntemleri aşağıda gösterilmiştir.

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

 /**
 * Class: URLBuilder
 * User: Gilad Tiram
 * Date: 6/12/13
 * Time: 4:02 PM
 * <p/>
 * <p/>
 * Utility that helps to build URL String
 */
 public class URLBuilder {


/**
 * Build URL string from Map of params. Nested Map and Collection is also supported
 *
 * @param params   Map of params for constructing the URL Query String
 * @param encoding encoding type. If not set the "UTF-8" is selected by default
 * @return String of type key=value&...key=value
 * @throws java.io.UnsupportedEncodingException
 *          if encoding isnot supported
 */
public static String httpBuildQuery(Map<String, Object> params, String encoding) {
    if (isEmpty(encoding)) {
        encoding = "UTF-8";
    }
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<String, Object> entry : params.entrySet()) {
        if (sb.length() > 0) {
            sb.append('&');
        }

        String name = entry.getKey();
        Object value = entry.getValue();


        if (value instanceof Map) {
            List<String> baseParam = new ArrayList<String>();
            baseParam.add(name);
            String str = buildUrlFromMap(baseParam, (Map) value, encoding);
            sb.append(str);

        } else if (value instanceof Collection) {
            List<String> baseParam = new ArrayList<String>();
            baseParam.add(name);
            String str = buildUrlFromCollection(baseParam, (Collection) value, encoding);
            sb.append(str);

        } else {
            sb.append(encodeParam(name));
            sb.append("=");
            sb.append(encodeParam(value));
        }


    }
    return sb.toString();
}

private static String buildUrlFromMap(List<String> baseParam, Map<Object, Object> map, String encoding) {
    StringBuilder sb = new StringBuilder();
    String token;

    //Build string of first level - related with params of provided Map
    for (Map.Entry<Object, Object> entry : map.entrySet()) {

        if (sb.length() > 0) {
            sb.append('&');
        }

        String name = String.valueOf(entry.getKey());
        Object value = entry.getValue();
        if (value instanceof Map) {
            List<String> baseParam2 = new ArrayList<String>(baseParam);
            baseParam2.add(name);
            String str = buildUrlFromMap(baseParam2, (Map) value, encoding);
            sb.append(str);

        } else if (value instanceof List) {
            List<String> baseParam2 = new ArrayList<String>(baseParam);
            baseParam2.add(name);
            String str = buildUrlFromCollection(baseParam2, (List) value, encoding);
            sb.append(str);
        } else {
            token = getBaseParamString(baseParam) + "[" + name + "]=" + encodeParam(value);
            sb.append(token);
        }
    }

    return sb.toString();
}

private static String buildUrlFromCollection(List<String> baseParam, Collection coll, String encoding) {
    StringBuilder sb = new StringBuilder();
    String token;
    if (!(coll instanceof List)) {
        coll = new ArrayList(coll);
    }
    List arrColl = (List) coll;

    //Build string of first level - related with params of provided Map
    for (int i = 0; i < arrColl.size(); i++) {

        if (sb.length() > 0) {
            sb.append('&');
        }

        Object value = (Object) arrColl.get(i);
        if (value instanceof Map) {
            List<String> baseParam2 = new ArrayList<String>(baseParam);
            baseParam2.add(String.valueOf(i));
            String str = buildUrlFromMap(baseParam2, (Map) value, encoding);
            sb.append(str);

        } else if (value instanceof List) {
            List<String> baseParam2 = new ArrayList<String>(baseParam);
            baseParam2.add(String.valueOf(i));
            String str = buildUrlFromCollection(baseParam2, (List) value, encoding);
            sb.append(str);
        } else {
            token = getBaseParamString(baseParam) + "[" + i + "]=" + encodeParam(value);
            sb.append(token);
        }
    }

    return sb.toString();
}


private static String getBaseParamString(List<String> baseParam) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < baseParam.size(); i++) {
        String s = baseParam.get(i);
        if (i == 0) {
            sb.append(s);
        } else {
            sb.append("[" + s + "]");
        }
    }
    return sb.toString();
}

/**
 * Check if String is either empty or null
 *
 * @param str string to check
 * @return true if string is empty. Else return false
 */
public static boolean isEmpty(String str) {
    return str == null || str.length() == 0;
}


private static String encodeParam(Object param) {
    try {
        return URLEncoder.encode(String.valueOf(param), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return URLEncoder.encode(String.valueOf(param));
    }
}

/* ========================================================================= */
/* Test functions                                                            */
/* ========================================================================= */


public static void main(String[] args) {
    //basicTest();
    //testWithMap();
    //testWithList();
    //testWithNestedMap();
    //testWithNestedList();
    testCompound();
}

private static void basicTest() {
    Map<String, Object> params = new LinkedHashMap<String, Object>();
    params.put("a", "1");
    params.put("b", "2");
    params.put("c", "3");

    System.out.println(httpBuildQuery(params, "UTF-8"));
}

private static void testWithMap() {
    Map<String, Object> params = new LinkedHashMap<String, Object>();
    params.put("a", "1");
    params.put("b", "2");

    Map<String, Object> cParams = new LinkedHashMap<String, Object>();
    cParams.put("c1", "c1val");
    cParams.put("c2", "c2val");
    params.put("c", cParams);

    System.out.println(httpBuildQuery(params, "UTF-8"));
}

private static void testWithNestedMap() {
    Map<String, Object> params = new LinkedHashMap<String, Object>();
    params.put("a", "1");
    params.put("b", "2");

    Map<String, Object> cParamsLevel1 = new LinkedHashMap<String, Object>();
    cParamsLevel1.put("cL1-1", "cLevel1-1val");
    cParamsLevel1.put("cL1-2", "cLevel1-2val");

    Map<String, Object> cParamsLevel2 = new LinkedHashMap<String, Object>();
    cParamsLevel2.put("cL2-1", "cLevel2-1val");
    cParamsLevel2.put("cL2-2", "cLevel2-2val");
    cParamsLevel1.put("cL1-3", cParamsLevel2);

    params.put("c", cParamsLevel1);

    System.out.println(httpBuildQuery(params, "UTF-8"));
}


private static void testWithList() {
    Map<String, Object> params = new LinkedHashMap<String, Object>();
    params.put("a", "1");
    params.put("b", "2");

    List<Object> cParams = new ArrayList<Object>();
    cParams.add("c1val");
    cParams.add("c2val");
    params.put("c", cParams);

    System.out.println(httpBuildQuery(params, "UTF-8"));
}


private static void testWithNestedList() {
    Map<String, Object> params = new LinkedHashMap<String, Object>();
    params.put("a", "1");
    params.put("b", "2");

    List<Object> cParamsLevel1 = new ArrayList<Object>();
    cParamsLevel1.add("cL1-val1");
    cParamsLevel1.add("cL12-val2");

    List<Object> cParamsLevel2 = new ArrayList<Object>();
    cParamsLevel2.add("cL2-val1");
    cParamsLevel2.add("cL2-val2");
    cParamsLevel1.add(cParamsLevel2);

    params.put("c", cParamsLevel1);

    System.out.println(httpBuildQuery(params, "UTF-8"));
}


private static void testCompound() {

    Map<String, Object> params = new LinkedHashMap<String, Object>();

    //flat
    params.put("a", "1");
    params.put("b", "2");

    //Map level 1
    Map<String, Object> cParamsLevel1 = new LinkedHashMap<String, Object>();
    cParamsLevel1.put("cL1-1", "cLevel1-1val");
    cParamsLevel1.put("cL1-2", "cLevel1-2val");

    //Map level 2
    Map<String, Object> cParamsLevel2 = new LinkedHashMap<String, Object>();
    cParamsLevel2.put("cL2-1", "cLevel2-1val");
    cParamsLevel2.put("cL2-2", "cLevel2-2val");
    cParamsLevel1.put("cL1-3", cParamsLevel2);

    params.put("c", cParamsLevel1);

    //List level 1
    List<Object> dParamsLevel1 = new ArrayList<Object>();
    dParamsLevel1.add("dL1-val1");
    dParamsLevel1.add("dL12-val2");

    //List level 2
    List<Object> dParamsLevel2 = new ArrayList<Object>();
    dParamsLevel2.add("dL2-val1");
    dParamsLevel2.add("dL2-val2");
    dParamsLevel1.add(dParamsLevel2);

    params.put("d", dParamsLevel1);

    System.out.println(httpBuildQuery(params, "UTF-8"));

}

}

Sonuçlarınızın kolay test için bu PHP işaret gerçek url sorgu dizesi gibi testleri ile sonuçlandı dize ekleyin. Örnek

http://localhost/test.php?a=1&b=2&c[cL1-1]=cLevel1-1val&c[cL1-2]=cLevel1-2val&c[cL1-3][cL2-1]=cLevel2-1val&c[cL1-3][cL2-2]=cLevel2-2val&d[0]=dL1-val1&d[1]=dL12-val2&d[2][0]=dL2-val1&d[2][1]=dL2-val2
<?php
var_dump($_REQUEST);
?>

Bu en kolay (ve en güvenilir) bir çözüm olmalıdır:

protected static String httpBuildQuery(List<? extends NameValuePair> parameters, String encoding) {
    return URLEncodedUtils.format(parameters, encoding).replace("*", "%2A");
}

Örnek kullanım:

List<NameValuePair> params = new ArrayList<NameValuePair>;
params.add(new BasicNameValuePair("key", "value"));

String queryString = httpBuildQuery(myParamList, "UTF-8");

Java (+) PHP kodlamak %2A tek fark olmalı yok iken yıldız kodlama değil.