在請求阿里雲的http接口,沒有sdk的狀況下,咱們須要本身手動拼接公共參數,而且作簽名。可是阿里雲官方的文檔寫的可能有點亂或者是我本身能力不太夠,反正我是看的一臉懵,因此我在他給的基礎上,本身手動封裝了一些方法。java
先上一些工具方法數組
1.hmacSHA1簽名工具app
private static byte[] hmacSHA1Signature(String accessKeySecret, String stringToSign) { try { String key = accessKeySecret + "&"; try { SecretKeySpec signKey = new SecretKeySpec(key.getBytes(), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(signKey); return mac.doFinal(stringToSign.getBytes()); } catch (Exception e) { throw new SignatureException("Failed to generate HMAC : " + e.getMessage()); } } catch (SignatureException e) { e.printStackTrace(); } return null; }
2.base64數組轉字符串工具
private static String newStringByBase64(byte[] bytes) throws UnsupportedEncodingException { if (bytes == null || bytes.length == 0) { return null; } return new String(Base64.getEncoder().encode(bytes)); }
3.特殊字符串轉義方法ui
private static String percentEncode(String value) { try { String urlEncodeOrignStr = URLEncoder.encode(value, "UTF-8"); String plusReplaced = urlEncodeOrignStr.replace("+", "%20"); String starReplaced = plusReplaced.replace("*", "%2A"); String waveReplaced = starReplaced.replace("%7E", "~"); return waveReplaced; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return value; }
4.公共參數拼接阿里雲
private static JSONObject commonParams() { JSONObject result = new JSONObject(); String SignatureNonce = Utils.generateId(); String format = "JSON"; String SignatureMethod = "HMAC-SHA1"; String SignatureVersion = "1.0"; String timestamp = DateUtil.getAliTimestamp(new Date()); result.put("SignatureMethod", SignatureMethod); result.put("SignatureNonce", SignatureNonce); result.put("SignatureVersion", SignatureVersion); result.put("AccessKeyId", accessKeyId); result.put("Timestamp", timestamp); result.put("Format", format); result.put("Version", "2017-03-21"); return result; }
5.簽名參數排序url
private static List<String> paramsSort(List<String> keys) { Collections.sort(keys); return keys; }
6.主題:全部參數進行簽名code
public static JSONObject commonParams(String httpMethod, JSONObject params) throws CoreServiceException { // 獲取公共參數 JSONObject commonParams = commonParams(); // 獲取須要簽名的參數,須要把公共參數和接口請求參數所有作簽名 JSONObject signParams = new JSONObject(); signParams.putAll(commonParams); signParams.putAll(params); // 對全部參數的key進行排序 Set<String> keySet = signParams.keySet(); List<String> keys = new ArrayList<>(); for (String key : keySet) { keys.add(key); } StringBuilder stringToSign = new StringBuilder(); keys = paramsSort(keys); // 遍歷生成須要簽名的字符串 for (String key : keys) { stringToSign.append("&"); stringToSign.append(key); stringToSign.append("="); stringToSign.append(percentEncode(signParams.getString(key))); } String string = stringToSign.toString(); String StringToSign = httpMethod + "&" + percentEncode("/") + "&" + percentEncode(string.substring(1)); String sign = ""; try { sign = newStringByBase64(hmacSHA1Signature(accessKeySecret, StringToSign)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if(StringUtils.isEmpty(sign)) { throw new CoreServiceException(OrgExceptype.DEFAULT, "阿里簽名失敗,請重試"); } // 將簽名放到公共參數中返回給須要的地方 commonParams.put("Signature", sign); return commonParams; }