参数解析能手 - ParamUtil

    我们来看看 参数解析能手 -

    主要由下面几个部分组成:

    给指定的uriString添加指定的参数 paramName 和值 paramValue.

    说明:

    • 如果原来的uriString没有指定的参数paramName,那么追加新的参数paramName和值paramValue.
    • 如果原来的uriString有指定的参数paramName,那么会被新的值替换paramValue.
    • 如果原来的uriString有指定的参数paramName,并且是多值类型(参数数组),那么多值参数中第一个会被新的值替换paramValue,其他的被丢弃.
    • 如果原来的uriString有参数,不管是拼接还是替换都会保持参数的原始顺序.
    • 如果uriString带有? 和参数,会先被截取,最后再拼接.
    • 如果uriString不带?,则自动增加?示例:

    返回:

    1. 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:
    1. String beforeUrl = "www.baidu.com";
    2. Map<String, String> keyAndArrayMap = new LinkedHashMap<>();
    3. keyAndArrayMap.put("province", "江苏省");
    4. keyAndArrayMap.put("city", "南通市");
    5. LOGGER.info(ParamUtil.addParameterSingleValueMap(beforeUrl, keyAndArrayMap, UTF8));

    返回:

    1. www.baidu.com?province=%E6%B1%9F%E8%8B%8F%E7%9C%81&city=%E5%8D%97%E9%80%9A%E5%B8%82

    示例2:

    1. String beforeUrl = "www.baidu.com?a=b";
    2. Map<String, String> keyAndArrayMap = new LinkedHashMap<>();
    3. keyAndArrayMap.put("province", "江苏省");
    4. keyAndArrayMap.put("city", "南通市");
    5. LOGGER.info(ParamUtil.addParameterSingleValueMap(beforeUrl, keyAndArrayMap, UTF8));

    返回:

    1. 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

    给指定的 uriString 添加参数 arrayValueMap,如果uri包含指定的参数名字,那么会被新的值替换.

    • 如果原来的 uriString 没有指定的参数paramName,那么循环arrayValueMap,追加新的参数paramName和值 paramValue.
    • 如果原来的 uriString 有指定的参数paramName,并且是多值类型(参数数组),那么多值参数中第一个会被新的值替换paramValue,其他的被丢弃.
    • 如果原来的uriString有参数,不管是拼接还是替换都会保持参数的原始顺序.
    • 如果 uriString 带有? 和参数,会先被截取,最后再拼接.
    • 如果 uriString 不带?,则自动增加?示例1:
    1. String beforeUrl = "www.baidu.com";
    2. Map<String, String[]> keyAndArrayMap = new LinkedHashMap<>();
    3. keyAndArrayMap.put("province", new String[] { "江苏省" });
    4. keyAndArrayMap.put("city", new String[] { "南通市" });
    5. LOGGER.info(ParamUtil.addParameterArrayValueMap(beforeUrl, keyAndArrayMap, UTF8));

    返回:

    1. 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:

    返回:

    1. 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.1 Map<String, String> toSingleValueMap(String queryString,String charsetType)

    将a=1&b=2这样格式的 queryString数据转换成map.

    说明:

    • 如果参数里面有相同名字的参数,那么转换的时候取第一个值
    • 内部使用 LinkedHashMap,map顺序依照 queryString 分隔的顺序示例:
    1. 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";
    2. LOGGER.info(JsonUtil.format(ParamUtil.toSingleValueMap(queryString, UTF8)));

    返回:

    1. {
    2. "sec_id": "MD5",
    3. "format": "xml",
    4. "sign": "cc945983476d615ca66cee41a883f6c1",
    5. "v": "2.0",
    6. "req_data":"%3Cauth_and_execute_req%3E%3Crequest_token%3E201511191eb5762bd0150ab33ed73976f7639893%3C%2Frequest_token%3E%3C%2Fauth_and_execute_req%3E",
    7. "service": "alipay.wap.auth.authAndExecute",
    8. "partner": "2088011438559510"
    9. }

    singleValueMap 转成自然排序的 queryString 字符串.

    示例:

    1. Map<String, String> map = new HashMap<>();
    2. map.put("service", "create_salesorder");
    3. map.put("_input_charset", "gbk");
    4. map.put("totalActual", "210.00");
    5. map.put("address", "江苏南通市通州区888组888号");
    6. 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 进行拼接示例:
    1. Map<String, String> map = new HashMap<>();
    2. map.put("totalActual", null);
    3. map.put(null, "create_salesorder");
    4. LOGGER.debug(ParamUtil.toNaturalOrderingQueryString(map));
    1. =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
    • 如果有key 是null,将使用 StringUtils.EMPTY 进行拼接
    • 如果singleValueMap有value 是null,将使用 StringUtils.EMPTY 进行拼接示例1:
    1. Map<String, String> singleValueMap = new LinkedHashMap<>();
    2. singleValueMap.put("province", "江苏省");
    3. singleValueMap.put("city", "南通市");
    4. LOGGER.info(ParamUtil.joinSingleValueMap(singleValueMap));

    返回:

    示例2:

    1. Map<String, String> map = new LinkedHashMap<>();
    2. map.put(null, null);
    3. map.put("a", "");
    4. map.put("b", null);
    5. map.put("c", "jim");
    6. LOGGER.info(ParamUtil.toQueryStringUseSingleValueMap(map));

    返回:

    1. =&a=&b=&c=jim

    只是简单的将map的key value 连接起来,最终格式类似于 url 的queryString.

    注意:

    • 该方法不会执行encode操作,使用原生值进行拼接
    • 按照传入的map key顺序进行排序,不会自行自动排序转换;如有有业务需求,先行排序完传入进来
    • 如果arrayValueMap有key 是null,将使用 StringUtils.EMPTY 进行拼接
    • 如果arrayValueMap有value的元素是null,将使用 StringUtils.EMPTY 进行拼接示例1:
    1. Map<String, String[]> keyAndArrayMap = new LinkedHashMap<>();
    2. keyAndArrayMap.put("province", new String[] { "江苏省", "浙江省" });
    3. keyAndArrayMap.put("city", new String[] { "南通市" });
    4. LOGGER.info(ParamUtil.joinArrayValueMap(keyAndArrayMap));

    返回:

    1. province=江苏省&province=浙江省&city=南通市

    示例2:

    1. Map<String, String[]> keyAndArrayMap = new LinkedHashMap<>();
    2. keyAndArrayMap.put("province", new String[] { "江苏省", null });
    3. keyAndArrayMap.put("city", new String[] { "南通市" });
    4. LOGGER.info(ParamUtil.joinArrayValueMap(keyAndArrayMap));

    返回:

    1. province=江苏省&province=&city=南通市

    3.1 String joinValuesOrderByIncludeKeys(Map<K, String> singleValueMap,K…includeKeys)

    singleValueMap中取到指定includeKeys key的value,连接起来(不使用任何连接符).

    说明:

    • 拼接的顺序按照 includeKeys 的顺序,目前适用于个别银行(比如汇付天下)需要将值拼接起来加密
    • 如果singleValueMap中的value是null,那么会以StringUtils.EMPTY替代,进行拼接示例:
    1. Map<String, String> map = new HashMap<>();
    2. map.put("service", "create_salesorder");
    3. map.put("paymentType", "unionpay_mobile");
    4. ParamUtil.joinValuesOrderByIncludeKeys(map, "service", "paymentType") = create_salesorderunionpay_mobile