Java tutorial
/* * Copyright (C) 2008 feilong * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.feilong.core.net; import static org.apache.commons.lang3.ArrayUtils.EMPTY_STRING_ARRAY; import static org.apache.commons.lang3.StringUtils.EMPTY; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.feilong.core.CharsetType; import com.feilong.core.bean.ConvertUtil; import com.feilong.core.lang.StringUtil; import com.feilong.core.util.MapUtil; import com.feilong.core.util.SortUtil; import static com.feilong.core.URIComponents.AMPERSAND; import static com.feilong.core.URIComponents.QUESTIONMARK; import static com.feilong.core.Validator.isNotNullOrEmpty; import static com.feilong.core.Validator.isNullOrEmpty; import static com.feilong.core.bean.ConvertUtil.toMap; import static com.feilong.core.util.MapUtil.newLinkedHashMap; import static com.feilong.core.util.SortUtil.sortByKeyAsc; /** * ??. * * @author <a href="http://feitianbenyue.iteye.com/">feilong</a> * @see "org.springframework.web.util.UriComponentsBuilder" * @see "org.apache.http.client.utils.URIBuilder" * @since 1.0.0 */ public final class ParamUtil { /** The Constant log. */ private static final Logger LOGGER = LoggerFactory.getLogger(ParamUtil.class); /** Don't let anyone instantiate this class. */ private ParamUtil() { //AssertionError?. ?????. ???. //see Effective Java 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } // ************************************addParameter****************************************************** /** * ?,uri????,?. * * <h3>:</h3> * <blockquote> * * <pre class="code"> * String uri = "http://www.feilong.com:8888/esprit-frontend/search.htm?{@code keyword=%E6%81%A4&page=}"; * String pageParamName = "label"; * String prePageNo = "2-5-8-12"; * LOGGER.info(ParamUtil.addParameter(uri, pageParamName, prePageNo, UTF8)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code http://www.feilong.com:8888/esprit-frontend/search.htm?keyword=%E6%81%A4&page=&label=2-5-8-12} * </pre> * * </blockquote> * * @param uriString * ? ?,?,??,<br> * ??, ? * @param paramName * ??? * @param parameValue * ?,? {@link String} * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return ?,uri????,?<br> * <code>uriString</code> nullempty, {@link StringUtils#EMPTY}<br> * @see #addParameterSingleValueMap(String, Map, String) */ public static String addParameter(String uriString, String paramName, Object parameValue, String charsetType) { return addParameterSingleValueMap(uriString, toMap(paramName, "" + parameValue), charsetType); } /** * ?,uri????,?. * * <h3>1:</h3> * <blockquote> * * <pre class="code"> * String beforeUrl = "www.baidu.com"; * Map{@code <String, String>} keyAndArrayMap = new LinkedHashMap{@code <String, String>}(); * * keyAndArrayMap.put("province", "??"); * keyAndArrayMap.put("city", "?"); * * LOGGER.info(ParamUtil.addParameterSingleValueMap(beforeUrl, keyAndArrayMap, UTF8)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code www.baidu.com?province=%E6%B1%9F%E8%8B%8F%E7%9C%81&city=%E5%8D%97%E9%80%9A%E5%B8%82} * </pre> * * </blockquote> * <h3>2:</h3> * <blockquote> * * <pre class="code"> * String beforeUrl = "www.baidu.com?a=b"; * Map{@code <String, String>} keyAndArrayMap = new LinkedHashMap{@code <String, String>}(); * * keyAndArrayMap.put("province", "??"); * keyAndArrayMap.put("city", "?"); * * LOGGER.info(ParamUtil.addParameterSingleValueMap(beforeUrl, keyAndArrayMap, UTF8)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code www.baidu.com?a=b&province=%E6%B1%9F%E8%8B%8F%E7%9C%81&city=%E5%8D%97%E9%80%9A%E5%B8%82} * </pre> * * </blockquote> * * @param uriString * the uri string * @param singleValueMap * singleValueMap param name value * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>uriString</code> nullempty, {@link StringUtils#EMPTY}<br> * @see #addParameterArrayValueMap(String, Map, String) */ public static String addParameterSingleValueMap(String uriString, Map<String, String> singleValueMap, String charsetType) { return addParameterArrayValueMap(uriString, MapUtil.toArrayValueMap(singleValueMap), charsetType); } /** * ?,uri????,?. * * <p> * ?<code>queryString</code> ?,??map,?? <code>arrayValueMap</code>;<br> * {@link LinkedHashMap},??map? * </p> * * <h3>1:</h3> * <blockquote> * * <pre class="code"> * String beforeUrl = "www.baidu.com"; * Map{@code <String, String[]>} keyAndArrayMap = new LinkedHashMap{@code <String, String[]>}(); * * keyAndArrayMap.put("receiver", new String[] { "", "feilong" }); * keyAndArrayMap.put("province", new String[] { "??" }); * keyAndArrayMap.put("city", new String[] { "?" }); * LOGGER.info(ParamUtil.addParameterArrayValueMap(beforeUrl, keyAndArrayMap, UTF8)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code www.baidu.com?receiver=%E9%91%AB%E5%93%A5&receiver=feilong&province=%E6%B1%9F%E8%8B%8F%E7%9C%81&city=%E5%8D%97%E9%80%9A%E5%B8%82} * </pre> * * </blockquote> * * * <h3>2:</h3> * <blockquote> * * <pre class="code"> * String beforeUrl = "www.baidu.com?a=b"; * Map{@code <String, String[]>} keyAndArrayMap = new LinkedHashMap{@code <String, String[]>}(); * keyAndArrayMap.put("province", new String[] { "??" }); * keyAndArrayMap.put("city", new String[] { "?" }); * LOGGER.info(ParamUtil.addParameterArrayValueMap(beforeUrl, keyAndArrayMap, UTF8)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code www.baidu.com?a=b&province=%E6%B1%9F%E8%8B%8F%E7%9C%81&city=%E5%8D%97%E9%80%9A%E5%B8%82} * </pre> * * </blockquote> * * @param uriString * the uri string * @param arrayValueMap * the name and array value map * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return ?,uri????,?<br> * <code>uriString</code> nullempty, {@link StringUtils#EMPTY}<br> * <code>arrayValueMap</code> nullempty, <code>uriString</code><br> * @see #addParameterArrayValueMap(String, String, Map, String) * @since 1.4.0 */ public static String addParameterArrayValueMap(String uriString, Map<String, String[]> arrayValueMap, String charsetType) { return addParameterArrayValueMap(uriString, URIUtil.getQueryString(uriString), arrayValueMap, charsetType); } /** * {@code a=1&b=2}????map (charsetType?nullempty keyvalue). * * <p> * {@link LinkedHashMap},map?? <code>queryString</code> ?? * </p> * * <h3>:</h3> * <blockquote> * * <pre class="code"> * String queryString = "{@code sec_id=MD5&format=xml&sign=cc945983476d615ca66cee41a883f6c1&v=2.0&req_data=%3Cauth_and_execute_req%3E%3Crequest_token%3E201511191eb5762bd0150ab33ed73976f7639893%3C%2Frequest_token%3E%3C%2Fauth_and_execute_req%3E&service=alipay.wap.auth.authAndExecute&partner=2088011438559510}"; * LOGGER.info(JsonUtil.format(ParamUtil.toSingleValueMap(queryString, UTF8))); * </pre> * * <b>:</b> * * <pre class="code"> * { * "sec_id": "MD5", * "format": "xml", * "sign": "cc945983476d615ca66cee41a883f6c1", * "v": "2.0", * "req_data":"%3Cauth_and_execute_req%3E%3Crequest_token%3E201511191eb5762bd0150ab33ed73976f7639893%3C%2Frequest_token%3E%3C%2Fauth_and_execute_req%3E", * "service": "alipay.wap.auth.authAndExecute", * "partner": "2088011438559510" * } * </pre> * * </blockquote> * * @param queryString * the query string * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>queryString</code> nullempty, {@link Collections#emptyMap()}<br> * @see #toSafeArrayValueMap(String, String) * @since 1.4.0 */ public static Map<String, String> toSingleValueMap(String queryString, String charsetType) { return MapUtil.toSingleValueMap(toSafeArrayValueMap(queryString, charsetType)); } /** * {@code a=1&b=2}????map (charsetType ?nullempty keyvalue). * * <p> * {@link LinkedHashMap},map?? <code>queryString</code> ?? * </p> * * <p> * ??:?? {@code &} , ?keyvalue = ? * </p> * * <h3>1:</h3> * <blockquote> * * <pre class="code"> * LOGGER.info(JsonUtil.format(ParamUtil.toSafeArrayValueMap("{@code a=1&b=2&a=5}", UTF8))); * </pre> * * <b>:</b> * * <pre class="code"> {"a": [ "1", "5" ], "b": ["2"] } * </pre> * * <hr> * * <pre class="code"> * LOGGER.info(JsonUtil.format(ParamUtil.toSafeArrayValueMap("{@code a=&b=2&a}", UTF8))); * </pre> * * <b>:</b> * * <pre class="code"> {"a": [ "", "" ], "b": ["2"] } * </pre> * * </blockquote> * * @param queryString * {@code a=1&b=2}?,?{@code a=1&a=1}?, map * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>queryString</code> nullempty, {@link Collections#emptyMap()}<br> * @see org.apache.commons.lang3.ArrayUtils#add(Object[], Object) * @see com.feilong.core.lang.StringUtil#split(String, String) * @since 1.4.0 */ static Map<String, String[]> toSafeArrayValueMap(String queryString, String charsetType) { if (isNullOrEmpty(queryString)) { return Collections.emptyMap(); } String[] nameAndValueArray = StringUtil.split(queryString, AMPERSAND); int length = nameAndValueArray.length; Map<String, String[]> safeArrayValueMap = newLinkedHashMap(length);// LinkedHashMap ??? for (int i = 0; i < length; ++i) { String[] tempArray = nameAndValueArray[i].split("=", 2); String key = decodeAndEncode(tempArray[0], charsetType); String value = tempArray.length == 2 ? tempArray[1] : EMPTY;//??,???,??? value = decodeAndEncode(value, charsetType); safeArrayValueMap.put(key, ArrayUtils.add(safeArrayValueMap.get(key), value)); } return safeArrayValueMap; } /** * map?? queryString. * * <p> * queryString??,singleValueMap key?,? {@link TreeMap},{@link LinkedHashMap}?? * </p> * * <h3>:</h3> * <blockquote> * * map, * * <pre class="code"> * Map{@code <String, String[]>} keyAndArrayMap = new HashMap{@code <String, String[]>}(); * keyAndArrayMap.put("name", new String[] { "jim", "feilong", "" }); * keyAndArrayMap.put("age", new String[] { "18" }); * keyAndArrayMap.put("love", new String[] { "sanguo" }); * </pre> * * : * * <pre class="code"> * LOGGER.info(ParamUtil.toSafeQueryString(keyAndArrayMap, UTF8)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code love=sanguo&age=18&name=jim&name=feilong&name=%E9%91%AB%E5%93%A5} * </pre> * * : * * <pre class="code"> * LOGGER.info(ParamUtil.toSafeQueryString(keyAndArrayMap, null)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code love=sanguo&age=18&name=jim&name=feilong&name=} * </pre> * * </blockquote> * * @param arrayValueMap * <code>request.getParamMap</code> * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>arrayValueMap</code> nullempty, {@link StringUtils#EMPTY}<br> * @see #toQueryStringUseArrayValueMap(Map) * @since 1.4.0 */ public static String toSafeQueryString(Map<String, String[]> arrayValueMap, String charsetType) { return toQueryStringUseArrayValueMap(toSafeArrayValueMap(arrayValueMap, charsetType)); } //********************************************************************************************* /** * <code>singleValueMap</code> ?<code>?</code> <code>queryString</code> . * * <p style="color:red"> * ?(?),? <b>??</b>,?encode?,<b></b> * </p> * * <h3>:</h3> * * <blockquote> * <p> * <code>singleValueMap</code> {@link SortUtil#sortByKeyAsc(Map)} ?,<br> * ?mapkeyvalue = ? ,<br> * ??entry?{@code &} ?,? url queryString, * </p> * * </blockquote> * * <h3>:</h3> * <blockquote> * * <pre class="code"> * Map{@code <String, String>} map = new HashMap{@code <String, String>}(); * map.put("service", "create_salesorder"); * map.put("_input_charset", "gbk"); * map.put("totalActual", "210.00"); * map.put("province", "??"); * map.put("city", "?"); * map.put("district", ""); * map.put("address", "??888888?"); * LOGGER.debug(ParamUtil.toNaturalOrderingQueryString(map)); * </pre> * * : * * <pre class="code"> * {@code _input_charset=gbk&address=??888888?&city=?&district=&province=??&service=create_salesorder&totalActual=210.00} * </pre> * * </blockquote> * * <h3> key value?:</h3> * * <blockquote> * <p> * <code>singleValueMap</code> ,key<code>null</code>, {@link NullPointerException}, * {@link SortUtil#sortByKeyAsc(Map)} ?, {@link TreeMap} ??null key;<br> * * value <code>null</code>, {@link StringUtils#EMPTY} * </p> * * </blockquote> * * <h3>:</h3> * * <blockquote> * * <pre class="code"> * * Map{@code <String, String>} map = new HashMap{@code <String, String>}(); * map.put("service", null); * map.put("totalActual", "210.00"); * map.put("province", "??"); * * LOGGER.debug(ParamUtil.toNaturalOrderingQueryString(map)); * * </pre> * * <b>:</b> * * <pre class="code"> * {@code province=??&service=&totalActual=210.00} * </pre> * * </blockquote> * * @param singleValueMap * ??? * @return <code>singleValueMap</code> nullempty, {@link StringUtils#EMPTY}<br> * ?<code>singleValueMap</code>??, {@link #toQueryStringUseSingleValueMap(Map)} * @see #toSafeQueryString(Map, String) * @since 1.4.0 */ public static String toNaturalOrderingQueryString(Map<String, String> singleValueMap) { return null == singleValueMap ? EMPTY : toQueryStringUseSingleValueMap(sortByKeyAsc(singleValueMap)); } /** * <code>singleValueMap</code>? queryString. * * <p> * ??mapkey value <code>singleValueMap</code>? ?,? url queryString, * ,???<code>param Name=name</code>,<code>param Value=zhangfei</code>, <code>name=zhangfei</code> * </p> * * <h3>:</h3> * <blockquote> * * <pre class="code"> * Map{@code <String, String>} singleValueMap = new LinkedHashMap{@code <String, String>}(); * * singleValueMap.put("province", "??"); * singleValueMap.put("city", "?"); * * LOGGER.info(ParamUtil.joinSingleValueMap(singleValueMap)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code province=??&city=?} * </pre> * * </blockquote> * * @param singleValueMap * the params map * @return <code>singleValueMap</code> nullempty, {@link StringUtils#EMPTY} <br> * ? <code>singleValueMap</code> ? {@link MapUtil#toArrayValueMap(Map)},? {@link #toQueryStringUseArrayValueMap(Map)} * @see MapUtil#toArrayValueMap(Map) * @see #toQueryStringUseArrayValueMap(Map) * @see <a href="http://www.leveluplunch.com/java/examples/build-convert-map-to-query-string/">build-convert-map-to-query-string</a> * @since 1.5.5 */ public static String toQueryStringUseSingleValueMap(Map<String, String> singleValueMap) { return toQueryStringUseArrayValueMap(MapUtil.toArrayValueMap(singleValueMap)); } /** * ??mapkey value ?,? url queryString. * * <h3>?:</h3> * * <blockquote> * <ul> * <li><span style="color:red">?encode?</span>,</li> * <li>map key??,???;,??</li> * </ul> * </blockquote> * * <h3>:</h3> * <blockquote> * * <pre class="code"> * Map{@code <String, String[]>} keyAndArrayMap = new LinkedHashMap{@code <String, String[]>}(); * * keyAndArrayMap.put("province", new String[] { "??", "?" }); * keyAndArrayMap.put("city", new String[] { "?" }); * LOGGER.info(ParamUtil.joinArrayValueMap(keyAndArrayMap)); * </pre> * * <b>:</b> * * <pre class="code"> * {@code province=??&province=?&city=?} * </pre> * * </blockquote> * * @param arrayValueMap * the array value map * @return <code>arrayValueMap</code> NullEmpty, {@link StringUtils#EMPTY}<br> * ? <code>arrayValueMap</code> ?QueryString * @see #joinParamNameAndValues(String, String[]) * @see <a href="http://www.leveluplunch.com/java/examples/build-convert-map-to-query-string/">build-convert-map-to-query-string</a> * @since 1.5.5 */ public static String toQueryStringUseArrayValueMap(Map<String, String[]> arrayValueMap) { if (isNullOrEmpty(arrayValueMap)) { return EMPTY; } int i = 0; StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String[]> entry : arrayValueMap.entrySet()) { sb.append(joinParamNameAndValues(entry.getKey(), entry.getValue())); if (i != arrayValueMap.size() - 1) {// ?& ? sb.append(AMPERSAND); } ++i; } return sb.toString(); } /** * ?keysvalue,?(<span style="color:red">?</span>). * * <p> * includeKeys?,? () ??<br> * mapvaluenull,{@link StringUtils#EMPTY} * </p> * * <h3>:</h3> * <blockquote> * * <pre class="code"> * Map{@code <String, String>} map = new HashMap{@code <String, String>}(); * map.put("service", "create_salesorder"); * map.put("paymentType", "unionpay_mobile"); * * LOGGER.info(ParamUtil.joinValues(map, "service", "paymentType")); * </pre> * * <b>:</b> * * <pre class="code"> * create_salesorderunionpay_mobile * </pre> * * </blockquote> * * @param <K> * the key type * @param singleValueMap * the map * @param includeKeys * ?key * @return <code>singleValueMap</code> null, {@link NullPointerException}<br> * <code>includeKeys</code> nullempty, {@link StringUtils#EMPTY}<br> * ? <code>includeKeys</code>,? <code>singleValueMap</code>?,?;<br> * ( <code>singleValueMap</code>keynull,{@link StringUtils#defaultString(String)} ?{@link StringUtils#EMPTY})<br> * @see org.apache.commons.lang3.StringUtils#defaultString(String) * @since 1.5.5 */ @SafeVarargs public static <K> String joinValuesOrderByIncludeKeys(Map<K, String> singleValueMap, K... includeKeys) { Validate.notNull(singleValueMap, "singleValueMap can't be null!"); if (isNullOrEmpty(includeKeys)) { return EMPTY; } StringBuilder sb = new StringBuilder(); for (K key : includeKeys) {//?? //?: valuenull,StringBuilder "null" , ? java.lang.AbstractStringBuilder#append(String) sb.append(StringUtils.defaultString(singleValueMap.get(key))); } return sb.toString(); } //******************************************************************************************* /** * parameter array value map. * * <p> * <code>queryString</code> ??,??map,?? <code>arrayValueMap</code>;<br> * {@link LinkedHashMap},??map? * </p> * * @param uriString * the uri string * @param queryString * the query * @param arrayValueMap * the name and array value map * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return the string * @since 1.4.0 */ static String addParameterArrayValueMap(String uriString, String queryString, Map<String, String[]> arrayValueMap, String charsetType) { Map<String, String[]> safeArrayValueMap = ObjectUtils.defaultIfNull(arrayValueMap, Collections.<String, String[]>emptyMap()); Map<String, String[]> arrayParamValuesMap = newLinkedHashMap(safeArrayValueMap.size()); //???queryString map if (isNotNullOrEmpty(queryString)) { arrayParamValuesMap.putAll(toSafeArrayValueMap(queryString, null)); } arrayParamValuesMap.putAll(safeArrayValueMap); return combineUrl(URIUtil.getFullPathWithoutQueryString(uriString), arrayParamValuesMap, charsetType); } /** * To safe array value map. * * <p> * {@link LinkedHashMap},??map? * </p> * * @param arrayValueMap * the array value map * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>arrayValueMap</code> nullempty, {@link Collections#emptyMap()}<br> */ private static Map<String, String[]> toSafeArrayValueMap(Map<String, String[]> arrayValueMap, String charsetType) { if (isNullOrEmpty(arrayValueMap)) { return Collections.emptyMap(); } Map<String, String[]> safeArrayValueMap = newLinkedHashMap(arrayValueMap.size()); // LinkedHashMap,??map? for (Map.Entry<String, String[]> entry : arrayValueMap.entrySet()) { String key = entry.getKey(); String[] paramValues = entry.getValue(); if (isNullOrEmpty(paramValues)) { LOGGER.warn("the param key:[{}] value is null", key); paramValues = EMPTY_STRING_ARRAY;// empty,?? } safeArrayValueMap.put(decodeAndEncode(key, charsetType), toSafeValueArray(paramValues, charsetType)); } return safeArrayValueMap; } /** * To safe value array. * * @param paramValues * the param values * @param charsetType * the charset type * @return the string[] * @since 1.6.2 */ private static String[] toSafeValueArray(String[] paramValues, String charsetType) { if (isNullOrEmpty(charsetType)) { return paramValues; } List<String> paramValueList = new ArrayList<String>(); for (String value : paramValues) { paramValueList.add(decodeAndEncode(value, charsetType)); } return ConvertUtil.toArray(paramValueList, String.class); } /** * ??. * * <p> * ,??? {@code paramName=name}, {@code paramValues zhangfei,guanyu},{@code name=zhangfei&name=guanyu} * </p> * * <h3>?:</h3> * <blockquote> * <ol> * <li>paramName ? {@link StringUtils#defaultString(String)}???</li> * </ol> * </blockquote> * * @param paramName * ??? * @param paramValues * ? * @return the string * @see java.lang.AbstractStringBuilder#append(String) * @see org.apache.commons.lang3.StringUtils#defaultString(String) * @see "org.springframework.web.servlet.view.RedirectView#appendQueryProperties(StringBuilder,Map, String)" * @since 1.4.0 */ private static String joinParamNameAndValues(String paramName, String[] paramValues) { StringBuilder sb = new StringBuilder(); for (int i = 0, j = paramValues.length; i < j; ++i) { //?: value null ,StringBuilder "null" , ? java.lang.AbstractStringBuilder#append(String) sb.append(StringUtils.defaultString(paramName)).append("=") .append(StringUtils.defaultString(paramValues[i])); if (i != j - 1) {// ?& ? sb.append(AMPERSAND); } } return sb.toString(); } /** * ?queryString()?(?);chromequery encoded???;ie????. * * <p> * ??encoded,decode?encode; * </p> * * <p> * ?decode(query,charsetType),? = * </p> * * @param value * the value * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>value</code> nullempty, {@link StringUtils#EMPTY}<br> * <code>charsetType</code> nullempty, <code>value</code><br> * ? {@link URIUtil#decode(String, String)} ? {@link URIUtil#encode(String, String)} * @see <a * href="http://stackoverflow.com/questions/15004593/java-request-getquerystring-value-different-between-chrome-and-ie-browser"> * java-request-getquerystring-value-different-between-chrome-and-ie-browser</a> * @since 1.4.0 */ private static String decodeAndEncode(String value, String charsetType) { if (isNullOrEmpty(value)) { return EMPTY; } return isNullOrEmpty(charsetType) ? value : URIUtil.encode(URIUtil.decode(value, charsetType), charsetType); } /** * url. * * @param beforePathWithoutQueryString * the before path without query string * @param arrayValueMap * the array value map * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>beforePathWithoutQueryString</code> nullempty, {@link StringUtils#EMPTY}<br> * <code>arrayValueMap</code> nullempty, <code>beforePathWithoutQueryString</code> * @since 1.4.0 */ static String combineUrl(String beforePathWithoutQueryString, Map<String, String[]> arrayValueMap, String charsetType) { if (isNullOrEmpty(beforePathWithoutQueryString)) { return EMPTY; } if (isNullOrEmpty(arrayValueMap)) {//? return return beforePathWithoutQueryString; } StringBuilder sb = new StringBuilder(); sb.append(beforePathWithoutQueryString); sb.append(QUESTIONMARK); sb.append(toSafeQueryString(arrayValueMap, charsetType)); return sb.toString(); } }