参数解析能手 - ParamUtil > 给个string 格式的url,拿出或者添加几个参数,有方便的方法吗? 我们来看看 参数解析能手 - `ParamUtil` 主要由下面几个部分组成:  ## 1.添加参数. 返回类型|方法 | Description :---- |:---- | :--------- String |addParameter(String uriString,String paramName,String paramValue,String charsetType) | 给指定的uriString添加指定的参数 paramName 和值 paramValue. String |addParameterSingleValueMap(String uriString,Map<String, String> singleValueMap,String charsetType) | 给指定的uriString添加指定的参数 singleValueMap. String |addParameterArrayValueMap(String uriString,Map<String, String[]> arrayValueMap,String charsetType) | 给指定的 uriString添加参数 arrayValueMap,如果uri包含指定的参数名字,那么会被新的值替换. ### 1.1 String addParameter(String uriString,String paramName,String paramValue,String charsetType) 给指定的uriString添加指定的参数 paramName 和值 paramValue. **说明:** - 如果原来的`uriString`没有指定的参数paramName,那么追加新的参数paramName和值paramValue. - 如果原来的`uriString`有指定的参数paramName,那么会被新的值替换paramValue. - 如果原来的`uriString`有指定的参数paramName,并且是多值类型(参数数组),那么多值参数中第一个会被新的值替换paramValue,其他的被丢弃. - 如果原来的`uriString`有参数,不管是拼接还是替换都会保持参数的原始顺序. - 如果`uriString`带有? 和参数,会先被截取,最后再拼接. - 如果`uriString`不带?,则自动增加? **示例:** ```JAVA String uri = "http://www.feilong.com:8888/esprit-frontend/search.htm?keyword=%E6%81%A4&page="; String pageParamName = "label"; String prePageNo = "2-5-8-12"; LOGGER.info(ParamUtil.addParameter(uri, pageParamName, prePageNo, UTF8)); ``` **返回:** ``` http://www.feilong.com:8888/esprit-frontend/search.htm?keyword=%E6%81%A4&page=&label=2-5-8-12 ``` ### 1.2 String addParameterSingleValueMap(String uriString,Map<String, String> singleValueMap,String charsetType) 给指定的uriString添加指定的参数 `singleValueMap`. **说明:** - 如果原来的 `uriString` 没有指定的参数paramName,那么循环arrayValueMap,追加新的参数paramName和值 paramValue. - 如果原来的 `uriString` 有指定的参数paramName,那么会被新的值替换paramValue. - 如果原来的 `uriString` 有指定的参数paramName,并且是多值类型(参数数组),那么多值参数中第一个会被新的值替换paramValue,其他的被丢弃. - 如果原来的 `uriString` 有参数,不管是拼接还是替换都会保持参数的原始顺序. - 如果 `uriString` 带有? 和参数,会先被截取,最后再拼接. - 如果 `uriString` 不带?,则自动增加? **示例1:** ```JAVA String beforeUrl = "www.baidu.com"; Map<String, String> keyAndArrayMap = new LinkedHashMap<>(); keyAndArrayMap.put("province", "江苏省"); keyAndArrayMap.put("city", "南通市"); LOGGER.info(ParamUtil.addParameterSingleValueMap(beforeUrl, keyAndArrayMap, UTF8)); ``` **返回:** ``` www.baidu.com?province=%E6%B1%9F%E8%8B%8F%E7%9C%81&city=%E5%8D%97%E9%80%9A%E5%B8%82 ``` **示例2:** ```JAVA String beforeUrl = "www.baidu.com?a=b"; Map<String, String> keyAndArrayMap = new LinkedHashMap<>(); keyAndArrayMap.put("province", "江苏省"); keyAndArrayMap.put("city", "南通市"); LOGGER.info(ParamUtil.addParameterSingleValueMap(beforeUrl, keyAndArrayMap, UTF8)); ``` **返回:** ``` 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 ``` ### 1.3 String addParameterArrayValueMap(String uriString,Map<String, String[]> arrayValueMap,String charsetType) 给指定的 `uriString` 添加参数 `arrayValueMap`,如果uri包含指定的参数名字,那么会被新的值替换. **说明:** - 如果原来的 `uriString` 没有指定的参数paramName,那么循环arrayValueMap,追加新的参数paramName和值 paramValue. - 如果原来的 `uriString` 有指定的参数paramName,那么会被新的值替换paramValue. - 如果原来的 `uriString` 有指定的参数paramName,并且是多值类型(参数数组),那么多值参数中第一个会被新的值替换paramValue,其他的被丢弃. - 如果原来的`uriString`有参数,不管是拼接还是替换都会保持参数的原始顺序. - 如果 `uriString` 带有? 和参数,会先被截取,最后再拼接. - 如果 `uriString` 不带?,则自动增加? **示例1:** ```JAVA String beforeUrl = "www.baidu.com"; Map<String, String[]> keyAndArrayMap = new LinkedHashMap<>(); keyAndArrayMap.put("receiver", new String[] { "鑫哥", "feilong" }); keyAndArrayMap.put("province", new String[] { "江苏省" }); keyAndArrayMap.put("city", new String[] { "南通市" }); LOGGER.info(ParamUtil.addParameterArrayValueMap(beforeUrl, keyAndArrayMap, UTF8)); ``` **返回:** ``` 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 ``` **示例2:** ```JAVA String beforeUrl = "www.baidu.com?a=b"; Map<String, String[]> keyAndArrayMap = new LinkedHashMap<>(); keyAndArrayMap.put("province", new String[] { "江苏省" }); keyAndArrayMap.put("city", new String[] { "南通市" }); LOGGER.info(ParamUtil.addParameterArrayValueMap(beforeUrl, keyAndArrayMap, UTF8)); ``` **返回:** ``` 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 ``` ## 2.转换. 返回类型|方法 | Description :---- |:---- | :--------- Map<String, String> |toSingleValueMap(String queryString,String charsetType) | 将a=1&b=2这样格式的 queryString数据转换成map. String |toNaturalOrderingQueryString(Map<String, String> singleValueMap) | 将 singleValueMap 转成自然排序的 queryString 字符串. String |toQueryStringUseSingleValueMap(Map<String, String> singleValueMap) | 将singleValueMap转成 queryString. String |toQueryStringUseArrayValueMap(Map<String, String[]> arrayValueMap) | 只是简单的将map的key value 连接起来,最终格式类似于 url 的queryString. ### 2.1 Map<String, String> toSingleValueMap(String queryString,String charsetType) 将a=1&b=2这样格式的 queryString数据转换成map. **说明:** - 如果参数里面有相同名字的参数,那么转换的时候取第一个值 - 内部使用 `LinkedHashMap`,map顺序依照 queryString 分隔的顺序 **示例:** ```JAVA String queryString = "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))); ``` **返回:** ```JSON { "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" } ``` ### 2.2 String toNaturalOrderingQueryString(Map<String, String> singleValueMap) 将 `singleValueMap` 转成自然排序的 `queryString` 字符串. **示例:** ```JAVA Map<String, String> map = new HashMap<>(); map.put("service", "create_salesorder"); map.put("_input_charset", "gbk"); map.put("totalActual", "210.00"); map.put("address", "江苏南通市通州区888组888号"); LOGGER.debug(ParamUtil.toNaturalOrderingQueryString(map)); ``` **返回:** _input_charset=gbk&address=江苏南通市通州区888组888号&service=create_salesorder&totalActual=210.00 **规则:** - 首先将 `singleValueMap` 使用 `SortUtil.sortMapByKeyAsc(Map)` 进行排序, - 然后将map的key和value 使用= 符号 连接,不同的entry之间再使用& 符号进行连接,最终格式类似于 url 的queryString **说明:** - 常用于和第三方对接数据(比如支付宝,生成 待签名的字符串) - 该方法不会执行encode操作,使用原生值进行拼接 - 对于 null key或者null value的处理: - 如果 `singleValueMap` 中, 如果有 key 是null,那么会使用 `StringUtils.EMPTY` 进行拼接; 如果有 value 是 null,那么会使用 `StringUtils.EMPTY` 进行拼接 **示例:** ```JAVA Map<String, String> map = new HashMap<>(); map.put("totalActual", null); map.put(null, "create_salesorder"); map.put("province", "江苏省"); LOGGER.debug(ParamUtil.toNaturalOrderingQueryString(map)); ``` **返回:** ``` =create_salesorder&province=江苏省&totalActual= ``` ### 2.3 String toQueryStringUseSingleValueMap(Map<String, String> singleValueMap) 将`singleValueMap`转成 `queryString`. **说明:** - 只是简单的将map的key value 按照 `singleValueMap`的顺序 连接起来,最终格式类似于 url 的`queryString`,比如,参数名字param Name=name,param Value=zhangfei,那么返回值是 name=zhangfei - 如果`singleValueMap`有key 是null,将使用 `StringUtils.EMPTY` 进行拼接 - 如果`singleValueMap`有value 是null,将使用 `StringUtils.EMPTY` 进行拼接 **示例1:** ```JAVA Map<String, String> singleValueMap = new LinkedHashMap<>(); singleValueMap.put("province", "江苏省"); singleValueMap.put("city", "南通市"); LOGGER.info(ParamUtil.joinSingleValueMap(singleValueMap)); ``` **返回:** ``` province=江苏省&city=南通市 ``` **示例2:** ```JAVA Map<String, String> map = new LinkedHashMap<>(); map.put(null, null); map.put("a", ""); map.put("b", null); map.put("c", "jim"); LOGGER.info(ParamUtil.toQueryStringUseSingleValueMap(map)); ``` **返回:** ``` =&a=&b=&c=jim ``` ### 2.4 String toQueryStringUseArrayValueMap(Map<String, String[]> arrayValueMap) 只是简单的将map的key value 连接起来,最终格式类似于 url 的`queryString`. **注意:** - 该方法不会执行encode操作,使用原生值进行拼接 - 按照传入的map key顺序进行排序,不会自行自动排序转换;如有有业务需求,先行排序完传入进来 - 如果`arrayValueMap`有key 是null,将使用 `StringUtils.EMPTY` 进行拼接 - 如果`arrayValueMap`有value的元素是null,将使用 `StringUtils.EMPTY` 进行拼接 **示例1:** ```JAVA Map<String, String[]> keyAndArrayMap = new LinkedHashMap<>(); keyAndArrayMap.put("province", new String[] { "江苏省", "浙江省" }); keyAndArrayMap.put("city", new String[] { "南通市" }); LOGGER.info(ParamUtil.joinArrayValueMap(keyAndArrayMap)); ``` **返回:** ``` province=江苏省&province=浙江省&city=南通市 ``` 示例2: ```JAVA Map<String, String[]> keyAndArrayMap = new LinkedHashMap<>(); keyAndArrayMap.put("province", new String[] { "江苏省", null }); keyAndArrayMap.put("city", new String[] { "南通市" }); LOGGER.info(ParamUtil.joinArrayValueMap(keyAndArrayMap)); ``` **返回:** ``` province=江苏省&province=&city=南通市 ``` ## 3.拼接. 返回类型|方法 | Description :---- |:---- | :--------- String |joinValuesOrderByIncludeKeys(Map<K, String> singleValueMap,K...includeKeys) | 在singleValueMap中取到指定includeKeys key的value,连接起来(不使用任何连接符). ### 3.1 String joinValuesOrderByIncludeKeys(Map<K, String> singleValueMap,K...includeKeys) 在`singleValueMap`中取到指定includeKeys key的value,连接起来(不使用任何连接符). **说明:** - 拼接的顺序按照 `includeKeys` 的顺序,目前适用于个别银行(比如汇付天下)需要将值拼接起来加密 - 如果`singleValueMap`中的value是null,那么会以`StringUtils.EMPTY`替代,进行拼接 **示例:** 场景: 拼接map中 key是 "service"以及 "paymentType"的 value ```JAVA Map<String, String> map = new HashMap<>(); map.put("service", "create_salesorder"); map.put("paymentType", "unionpay_mobile"); ParamUtil.joinValuesOrderByIncludeKeys(map, "service", "paymentType") = create_salesorderunionpay_mobile ```