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.discovery.darchrow.net; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; 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.slf4j.Logger; import org.slf4j.LoggerFactory; import com.discovery.darchrow.bean.ConvertUtil; import com.discovery.darchrow.lang.CharsetType; import com.discovery.darchrow.lang.StringUtil; import com.discovery.darchrow.util.MapUtil; import com.discovery.darchrow.util.Validator; /** * ??. * * @author 2010-4-15 ?04:01:29 */ public final class ParamUtil { /** The Constant LOGGER. */ 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!"); } /** * ??,???. <br> * * <ol> * <li>? a z ?????? </li> * <li>????&??</li> * <li>?????.</li> * <li><span style="color:red">?: ???? encoding ?</span></li> * </ol> * * <h3>??:</h3> <blockquote> * <ol> * <li>{@code if isNullOrEmpty(filePath)---->} return {@link org.apache.commons.lang3.StringUtils#EMPTY}</li> * <li>paramsMap to naturalOrderingMap(TreeMap)</li> * <li>for naturalOrderingMap's entrySet(),join key and value use =,join each entry use &</li> * </ol> * </blockquote> * * @param paramsMap * ??? * @return the string * @since 1.2.0 */ public static String toNaturalOrderingString(Map<String, String> paramsMap) { if (Validator.isNullOrEmpty(paramsMap)) { return StringUtils.EMPTY; } StringBuilder sb = new StringBuilder(); Map<String, String> naturalOrderingMap = new TreeMap<String, String>(paramsMap); int i = 0; int size = naturalOrderingMap.size(); for (Map.Entry<String, String> entry : naturalOrderingMap.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value); // ??? & if (i != size - 1) { sb.append("&"); } ++i; } String naturalOrderingString = sb.toString(); if (LOGGER.isDebugEnabled()) { LOGGER.debug(naturalOrderingString); } return naturalOrderingString; } // ************************************addParameter****************************************************** /** * ? ???. * * @param url * the url * @param paramName * ??? * @param parameValue * ? * @param charsetType * the charset type * @return ? ??? */ public static String addParameter(String url, String paramName, Object parameValue, String charsetType) { URI uri = URIUtil.create(url, charsetType); return addParameter(uri, 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, CharsetType.UTF8)); * </pre> * * : * * <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, CharsetType.UTF8)); * </pre> * * : * * <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, CharsetType.UTF8)); * </pre> * * : * * <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, CharsetType.UTF8)); * </pre> * * : * * <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(URI, 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); } /** * ?. * * <p> * uri????,?,?{@code a=1&a=2},a,[3,4],{@code a=3&a=4}. * </p> * * @param uri * ? ?,?,??,<br> * ??, ? * @param arrayValueMap * singleValueMap request.getParameterMap * @param charsetType * ??, {@link CharsetType}<br> * <span style="color:green">null empty,?,?</span><br> * ??,??,ie?chrome? url ,? * @return <code>uri</code> null, {@link StringUtils#EMPTY}<br> */ public static String addParameterArrayValueMap(URI uri, Map<String, String[]> arrayValueMap, String charsetType) { return null == uri ? StringUtils.EMPTY : addParameterArrayValueMap(uri.toString(), uri.getRawQuery(), arrayValueMap, charsetType); } /** * ? ???. * * @param url * the url * @param nameAndValuesMap * nameAndValueMap param name value * @param charsetType * the charset type * @return ? ??? */ public static String addParameterArrayMap(String url, Map<String, String[]> nameAndValuesMap, String charsetType) { URI uri = URIUtil.create(url, charsetType); return addParameterArrayMap(uri, nameAndValuesMap, charsetType); } /** * ? ???. * * @param url * the url * @param nameAndValueMap * nameAndValueMap param name value * @param charsetType * the charset type * @return the string */ public static String addParameterValueMap(String url, Map<String, String> nameAndValueMap, String charsetType) { Map<String, String[]> keyAndArrayMap = new HashMap<String, String[]>(); if (Validator.isNotNullOrEmpty(nameAndValueMap)) { for (Map.Entry<String, String> entry : nameAndValueMap.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); keyAndArrayMap.put(key, new String[] { value }); } } return addParameterArrayMap(url, keyAndArrayMap, charsetType); } /** * ? ???. * * @param uri * URI ? (URI),<br> * ? ?,?,??,<br> * ??, ? * @param paramName * ??? * @param parameValue * ? * @param charsetType * ? * @return ? ??? */ public static String addParameter(URI uri, String paramName, Object parameValue, String charsetType) { Map<String, String[]> map = new HashMap<String, String[]>(); map.put(paramName, new String[] { parameValue.toString() }); return addParameterArrayMap(uri, map, charsetType); } /** * ? <br> * ?????a=1&a=2,a,[3,4] a=3&a=4. * * @param uri * URI ? (URI),<br> * ? ?,?,??,<br> * ??, ? * @param nameAndValueMap * nameAndValueMap request.getParameterMap * @param charsetType * ? * @return ? ??? */ public static String addParameterArrayMap(URI uri, Map<String, String[]> nameAndValueMap, String charsetType) { if (null == uri) { throw new IllegalArgumentException("uri can not be null!"); } if (Validator.isNullOrEmpty(nameAndValueMap)) { throw new IllegalArgumentException("nameAndValueMap can not be null!"); } // *********************************************************************** String url = uri.toString(); String before = URIUtil.getBeforePath(url); // *********************************************************************** // getQuery() URI ?? // getRawQuery() URI ? URI ???? URI String query = uri.getRawQuery(); // *********************************************************************** Map<String, String[]> map = new LinkedHashMap<String, String[]>(); // url?? if (Validator.isNullOrEmpty(query)) { // nothing to do } else { Map<String, String[]> originalMap = URIUtil.parseQueryToArrayMap(query, null); map.putAll(originalMap); } map.putAll(nameAndValueMap); // ************************************************************** return URIUtil.getEncodedUrlByArrayMap(before, map, charsetType); } // ********************************removeParameter********************************************************************* /** * ?. * * @param url * the url * @param paramName * the param name * @param charsetType * ? * @return the string */ public static String removeParameter(String url, String paramName, String charsetType) { URI uri = URIUtil.create(url, charsetType); return removeParameter(uri, paramName, charsetType); } /** * ?. * * @param uri * the uri * @param paramName * the param name * @param charsetType * ? * @return the string */ private static String removeParameter(URI uri, String paramName, String charsetType) { List<String> paramNameList = null; if (Validator.isNotNullOrEmpty(paramName)) { paramNameList = new ArrayList<String>(); paramNameList.add(paramName); } return removeParameterList(uri, paramNameList, charsetType); } /** * ?. * * @param url * the url * @param paramNameList * the param name list * @param charsetType * ? * @return the string */ public static String removeParameterList(String url, List<String> paramNameList, String charsetType) { URI uri = URIUtil.create(url, charsetType); return removeParameterList(uri, paramNameList, charsetType); } /** * ?. * * @param uri * the uri * @param paramNameList * the param name list * @param charsetType * ? * @return the string */ public static String removeParameterList(URI uri, List<String> paramNameList, String charsetType) { if (null == uri) { return ""; } String url = uri.toString(); // paramNameList null if (Validator.isNullOrEmpty(paramNameList)) { return url; } // *********************************************************************** String before = URIUtil.getBeforePath(url); // *********************************************************************** // URI ? URI ???? URI String query = uri.getRawQuery(); // *********************************************************************** // url?? if (Validator.isNullOrEmpty(query)) { // ?? return url; } else { Map<String, String[]> map = URIUtil.parseQueryToArrayMap(query, null); for (String paramName : paramNameList) { map.remove(paramName); } return URIUtil.getEncodedUrlByArrayMap(before, map, charsetType); } } // **************************************retentionParams******************************************************** /** * url?? ?. * * @param url * the url * @param paramNameList * the param name list * @param charsetType * ? * @return the string */ public static String retentionParamList(String url, List<String> paramNameList, String charsetType) { URI uri = URIUtil.create(url, charsetType); return retentionParamList(uri, paramNameList, charsetType); } /** * ??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> * * : * * <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 (Validator.isNullOrEmpty(arrayValueMap)) { return StringUtils.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(URIComponents.AMPERSAND); } ++i; } return sb.toString(); } /** * url?? ?. * * @param uri * the uri * @param paramNameList * the param name list * @param charsetType * ? * @return the string */ public static String retentionParamList(URI uri, List<String> paramNameList, String charsetType) { if (null == uri) { return ""; } else { String url = uri.toString(); // paramNameList null if (Validator.isNullOrEmpty(paramNameList)) { return url; } String before = URIUtil.getBeforePath(url); // *********************************************************************** // URI ? URI ???? URI String query = uri.getRawQuery(); // *********************************************************************** // url?? if (Validator.isNullOrEmpty(query)) { // ?? return url; } else { Map<String, String[]> map = new LinkedHashMap<String, String[]>(); Map<String, String[]> originalMap = URIUtil.parseQueryToArrayMap(query, null); for (String paramName : paramNameList) { map.put(paramName, originalMap.get(paramName)); } return URIUtil.getEncodedUrlByArrayMap(before, map, 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}", CharsetType.UTF8))); * </pre> * * : * * <pre class="code"> {"a": [ "1", "5" ], "b": ["2"] } * </pre> * * <hr> * * <pre class="code"> * LOGGER.info(JsonUtil.format(ParamUtil.toSafeArrayValueMap("{@code a=&b=2&a}", CharsetType.UTF8))); * </pre> * * : * * <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 */ public static Map<String, String[]> toSafeArrayValueMap(String queryString, String charsetType) { if (Validator.isNullOrEmpty(queryString)) { return Collections.emptyMap(); } String[] nameAndValueArray = StringUtil.split(queryString, URIComponents.AMPERSAND); int length = nameAndValueArray.length; Map<String, String[]> safeArrayValueMap = MapUtil.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] : StringUtils.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, CharsetType.UTF8)); * </pre> * * : * * <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> * * : * * <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)); } /** * 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 */ private 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 = MapUtil.newLinkedHashMap(safeArrayValueMap.size()); //???queryString map if (Validator.isNotNullOrEmpty(queryString)) { arrayParamValuesMap.putAll(toSafeArrayValueMap(queryString, null)); } arrayParamValuesMap.putAll(safeArrayValueMap); return combineUrl(URIUtil.getFullPathWithoutQueryString(uriString), arrayParamValuesMap, charsetType); } /** * ?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 (Validator.isNullOrEmpty(value)) { return StringUtils.EMPTY; } return Validator.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 */ private static String combineUrl(String beforePathWithoutQueryString, Map<String, String[]> arrayValueMap, String charsetType) { if (Validator.isNullOrEmpty(beforePathWithoutQueryString)) { return StringUtils.EMPTY; } if (Validator.isNullOrEmpty(arrayValueMap)) {//? return return beforePathWithoutQueryString; } StringBuilder sb = new StringBuilder(); sb.append(beforePathWithoutQueryString); sb.append(URIComponents.QUESTIONMARK); sb.append(toSafeQueryString(arrayValueMap, charsetType)); return sb.toString(); } /** * 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 (Validator.isNullOrEmpty(arrayValueMap)) { return Collections.emptyMap(); } Map<String, String[]> safeArrayValueMap = MapUtil.newLinkedHashMap(arrayValueMap.size()); // LinkedHashMap,??map? for (Map.Entry<String, String[]> entry : arrayValueMap.entrySet()) { String key = entry.getKey(); String[] paramValues = entry.getValue(); if (Validator.isNullOrEmpty(paramValues)) { LOGGER.warn("the param key:[{}] value is null", key); paramValues = ArrayUtils.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 (Validator.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(URIComponents.AMPERSAND); } } return sb.toString(); } }