原代码
public static String sendByPost(String url, int soTimeout, int connectTimeout, String goodsSerial) {
// logger.info("请求地址为:" + url);
String bodyString = "{\"sku\":[\"" + goodsSerial + "\"]}";
String stringToSign = "";
String date = new Date().toGMTString();
Long currentTimeMillis = System.currentTimeMillis();
MessageDigest md = MessageDigest.getInstance(MessageDigestAlgorithms.MD5);
String contentMD5 = new String(Base64.getEncoder().encode(md.digest(bodyString.getBytes())));
System.out.println(bodyString);
String[] split = url.split("com");
// HTTP请求URI
HttpPost request = new HttpPost(url);
request.addHeader("Authorization", token );
request.addHeader("Accept", "application/json; charset=utf-8");
request.addHeader("Content-MD5", contentMD5);
request.addHeader("Date", date);
request.addHeader("content-type", "application/json; charset=utf-8");
request.addHeader("PathAndParameters", split[split.length - 1]);
request.addHeader("x-ca-key", appKey);
request.addHeader("x-ca-signature-method", "HmacSHA256");
request.addHeader("x-ca-signature-headers", "x-ca-signature-method,x-ca-timestamp,x-ca-key,");
request.addHeader("x-ca-timestamp", currentTimeMillis.toString());
stringToSign = "POST" + "\napplication/json; charset=utf-8\n" + contentMD5
+ "\napplication/json; charset=utf-8\n" + date + "\nx-ca-key:203837880"
+ "\nx-ca-signature-method:HmacSHA256" + "\nx-ca-timestamp:" + currentTimeMillis + "\n"
+ split[split.length - 1];
try {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
hmacSha256.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));
byte[] md5Result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = new String(Base64.getEncoder().encode(md5Result));
request.addHeader("X-Ca-Signature", sign);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
request.setEntity(new StringEntity(bodyString ));
String message = sendRequest(request, soTimeout, connectTimeout);
// logger.info(",请求结果为:=" + message);
return message;
} catch (Exception e) {
e.printStackTrace();
logger.info(",请求结果为:=" + e);
}
return null;
}
经测试发现对中文字符无法通过Content-MD5的签名认证,返回为Content-MD5验证失败
比如传输 A108662-12×500ml 则显示返回Content-MD5验证失败,A108662则可以通过验证。
但是使用postman可以直接通过。
猜想为中文字符的部分在传输时被转为unicode,然后在阿里云验证时候使用的unicode去进行加密验证,而postman能通过则是因为他传输的是流,application/json请求头传输流。
于是我替换
request.setEntity(new StringEntity(bodyString ));
为
request.setEntity(new ByteArrayEntity(bodyString.getBytes()));
这样可以通过阿里云验证,但是返回的结果会将特殊字符及中文转为unicode编码
于是我们需要手动将unicode部分转为中文
上最终代码
public static String sendAlaDinByPost(String url, int soTimeout, int connectTimeout, String goodsSerial) {
// logger.info("请求地址为:" + url);
String bodyString = "{\"sku\":[\"" + goodsSerial + "\"]}";
String stringToSign = "";
String date = new Date().toGMTString();
Long currentTimeMillis = System.currentTimeMillis();
MessageDigest md = MessageDigest.getInstance(MessageDigestAlgorithms.MD5);
String contentMD5 = new String(Base64.getEncoder().encode(md.digest(bodyString.getBytes())));
System.out.println(bodyString);
String[] split = url.split("com");
// HTTP请求URI
HttpPost request = new HttpPost(url);
request.addHeader("Authorization", token );
request.addHeader("Accept", "application/json; charset=utf-8");
request.addHeader("Content-MD5", contentMD5);
request.addHeader("Date", date);
request.addHeader("content-type", "application/json; charset=utf-8");
request.addHeader("PathAndParameters", split[split.length - 1]);
request.addHeader("x-ca-key", appKey);
request.addHeader("x-ca-signature-method", "HmacSHA256");
request.addHeader("x-ca-signature-headers", "x-ca-signature-method,x-ca-timestamp,x-ca-key,");
request.addHeader("x-ca-timestamp", currentTimeMillis.toString());
stringToSign = "POST" + "\napplication/json; charset=utf-8\n" + contentMD5
+ "\napplication/json; charset=utf-8\n" + date + "\nx-ca-key:203837880"
+ "\nx-ca-signature-method:HmacSHA256" + "\nx-ca-timestamp:" + currentTimeMillis + "\n"
+ split[split.length - 1];
try {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
hmacSha256.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));
byte[] md5Result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = new String(Base64.getEncoder().encode(md5Result));
request.addHeader("X-Ca-Signature", sign);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
request.setEntity(new ByteArrayEntity(bodyString.getBytes()));
String message = sendRequest(request, soTimeout, connectTimeout);
// logger.info(",请求结果为:=" + message);
return StringUtil.decodeUnicode(message);
} catch (Exception e) {
e.printStackTrace();
logger.info(",请求结果为:=" + e);
}
return null;
}
stringutil
public static String decodeUnicode(String unicodeStr) {
Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
Matcher matcher = pattern.matcher(unicodeStr);
char ch;
while (matcher.find()) {
// group
String group = matcher.group(2);
// ch:'李四'
ch = (char) Integer.parseInt(group, 16);
// group1
String group1 = matcher.group(1);
unicodeStr = unicodeStr.replace("\\"+group1, ch + "");
}
return unicodeStr.trim();
}