京东联盟签名算法

京东联盟(union.jd.com)的开放平台(union.jd.com/openplatform)的API是不需要授权的,所以可以不用获取Access token直接使用。
平台提供的SDK不支持Java11,所以只能自己反编译得到签名算法:

private String sign(Map<String, String> data) {
	StringBuilder builder = new StringBuilder(secretkey);
	for (Map.Entry<String, String> entry : data.entrySet()) {
		String name = (String) entry.getKey();
		String value = (String) entry.getValue();
		if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value)) {
			builder.append(name).append(value);
		}
	}
	builder.append(secretkey);
	return DigestUtils.md5Hex(builder.toString()).toUpperCase();
}

完整的订单查询接口实现:

	/**
	 * API地址:union.jd.com/openplatform/api/650
	 */
	public void query() {
		LocalDateTime time = LocalDateTime.now();
		String queryTimestamp = time.format(DateTimeFormatter.ofPattern("yyyyMMddHH"));
		Map<String, Map<String, Object>> data = new HashMap<>(1);
		Map<String, Object> subData = new HashMap<>(4);
		data.put("orderReq", subData);
		subData.put("pageNo", 1);
		subData.put("pageSize", 20);
		subData.put("type", 1);
		subData.put("time", queryTimestamp);
		Map<String, String> requestData = requestData(data, "jd.union.open.order.query");
		String result = request(requestData);
		System.out.println(result);
	}
	/**
	 * 生成请求参数
	 */
	private Map<String, String> requestData(Map<String, Map<String, Object>> data, String method) {
		Map<String, String> requestData = new TreeMap<String, String>();
		LocalDateTime time = LocalDateTime.now();
		String timestamp = time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
		requestData.put("v", "1.0");
		requestData.put("format", "json");
		requestData.put("sign_method", "md5");
		requestData.put("timestamp", timestamp);
		requestData.put("app_key", this.jdAppkey);
		requestData.put("method", method);
		requestData.put("param_json", JAVA2JSON.java2Json(data));
		requestData.put("sign", sign(requestData));
		return requestData;
	}
	/**
	 * 签名
	 */
	private String sign(Map<String, String> data) {
		StringBuilder builder = new StringBuilder(this.jdSecretkey);
		for (Map.Entry<String, String> entry : data.entrySet()) {
			String name = (String) entry.getKey();
			String value = (String) entry.getValue();
			if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value)) {
				builder.append(name).append(value);
			}
		}
		builder.append(this.jdSecretkey);
		return DigestUtils.md5Hex(builder.toString()).toUpperCase();
	}
	/**
	 * 发送请求
	 */
	private String request(Map<String, String> requestData) {
		String queryString = requestData.entrySet().stream()
			.map(entry -> entry.getKey() + "=" + CommonUtils.urlEncoding(entry.getValue()))
			.collect(Collectors.joining("&"));
		return HTTPUtils.get(JD_QUERY_URL + queryString);
	}