package com.atguigu.aliyunvod.util;
import com.atguigu.aliyunvod.Main;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Logger;
/**
* @author helen
* @since 2019/3/7
*/
public class AliyunVodAPIUtils {
//账号AccessKey信息请填写(必选)
private static String access_key_id = "你的access_key_id";
//账号AccessKey信息请填写(必选)
private static String access_key_secret = "你的access_key_secret";
//STS临时授权方式访问时该参数为必选,使用主账号AccessKey和RAM子账号AccessKey不需要填写
private static String security_token = "";
//以下参数不需要修改
private final static String VOD_DOMAIN = "http://vod.cn-shanghai.aliyuncs.com";
private final static String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private final static String HTTP_METHOD = "GET";
private final static String HMAC_SHA1_ALGORITHM = "HmacSHA1";
private final static String UTF_8 = "utf-8";
private final static Logger LOG = Logger.getLogger(AliyunVodAPIUtils.class.getName());
/**
* 生成视频点播OpenAPI公共参数
* 不需要修改
* @return
*/
public static Map<String, String> generatePublicParamters() {
Map<String, String> publicParams = new HashMap<>();
publicParams.put("Format", "JSON");
publicParams.put("Version", "2017-03-21");
publicParams.put("AccessKeyId", access_key_id);
publicParams.put("SignatureMethod", "HMAC-SHA1");
publicParams.put("Timestamp", generateTimestamp());
publicParams.put("SignatureVersion", "1.0");
publicParams.put("SignatureNonce", generateRandom());
if (security_token != null && security_token.length() > 0) {
publicParams.put("SecurityToken", security_token);
}
return publicParams;
}
/**
* 生成OpenAPI地址
* @param privateParams
* @return
* @throws Exception
*/
public static String generateOpenAPIURL(Map<String, String> publicParams, Map<String, String> privateParams) {
return generateURL(VOD_DOMAIN, HTTP_METHOD, publicParams, privateParams);
}
/**
* @param domain 请求地址
* @param httpMethod HTTP请求方式GET,POST等
* @param publicParams 公共参数
* @param privateParams 接口的私有参数
* @return 最后的url
*/
private static String generateURL(String domain, String httpMethod, Map<String, String> publicParams, Map<String, String> privateParams) {
List<String> allEncodeParams = getAllParams(publicParams, privateParams);
String cqsString = getCQS(allEncodeParams);
out("CanonicalizedQueryString = " + cqsString);
String stringToSign = httpMethod + "&" + percentEncode("/") + "&" + percentEncode(cqsString);
out("StringtoSign = " + stringToSign);
String signature = hmacSHA1Signature(access_key_secret, stringToSign);
out("Signature = " + signature);
return domain + "?" + cqsString + "&" + percentEncode("Signature") + "=" + percentEncode(signature);
}
private static List<String> getAllParams(Map<String, String> publicParams, Map<String, String> privateParams) {
List<String> encodeParams = new ArrayList<String>();
if (publicParams != null) {
for (String key : publicParams.keySet()) {
String value = publicParams.get(key);
//将参数和值都urlEncode一下。
String encodeKey = percentEncode(key);
String encodeVal = percentEncode(value);
encodeParams.add(encodeKey + "=" + encodeVal);
}
}
if (privateParams != null) {
for (String key : privateParams.keySet()) {
String value = privateParams.get(key);
//将参数和值都urlEncode一下。
String encodeKey = percentEncode(key);
String encodeVal = percentEncode(value);
encodeParams.add(encodeKey + "=" + encodeVal);
}
}
return encodeParams;
}
/**
* 参数urlEncode
*
* @param value
* @return
*/
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;
}
/**
* 获取CQS 的字符串
*
* @param allParams
* @return
*/
private static String getCQS(List<String> allParams) {
AliyunVodAPIUtils.ParamsComparator paramsComparator = new AliyunVodAPIUtils.ParamsComparator();
Collections.sort(allParams, paramsComparator);
String cqString = "";
for (int i = 0; i < allParams.size(); i++) {
cqString += allParams.get(i);
if (i != allParams.size() - 1) {
cqString += "&";
}
}
return cqString;
}
private static class ParamsComparator implements Comparator<String> {
@Override
public int compare(String lhs, String rhs) {
return lhs.compareTo(rhs);
}
}
private static String hmacSHA1Signature(String accessKeySecret, String stringtoSign) {
try {
String key = accessKeySecret + "&";
try {
SecretKeySpec signKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signKey);
byte[] rawHmac = mac.doFinal(stringtoSign.getBytes());
//按照Base64 编码规则把上面的 HMAC 值编码成字符串,即得到签名值(Signature)
return new String(new BASE64Encoder().encode(rawHmac));
} catch (Exception e) {
throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
}
} catch (SignatureException e) {
e.printStackTrace();
}
return "";
}
/**
* 生成随机数
*
* @return
*/
private static String generateRandom() {
String signatureNonce = UUID.randomUUID().toString();
return signatureNonce;
}
/**
* 生成当前UTC时间戳
*
* @return
*/
public static String generateTimestamp() {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
df.setTimeZone(new SimpleTimeZone(0, "GMT"));
return df.format(date);
}
public static String httpGet(String url) throws Exception {
CloseableHttpClient httpClient = null;
try {
httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet();
httpGet.setURI(new URI(url));
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(3000)
.setSocketTimeout(3000)
.build();
httpGet.setConfig(requestConfig);
HttpResponse result = httpClient.execute(httpGet);
String str;
try {
/**读取服务器返回过来的json字符串数据**/
str = EntityUtils.toString(result.getEntity());
EntityUtils.consume(result.getEntity());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
out(str);
// 这里可以解析视频云点播服务端的响应结果
return str;
} catch (URISyntaxException e) {
e.printStackTrace();
throw e;
} catch (ClientProtocolException e) {
e.printStackTrace();
throw e;
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
if (httpClient != null)
httpClient.close();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
private static void out(String newLine) {
// System.out.println(newLine);
LOG.info(newLine);
}
}
阿里云API、SDK对接工具类
需积分: 0 160 浏览量
更新于2024-02-12
收藏 4KB ZIP 举报
阿里云API和SDK对接工具类是开发者在与阿里云服务进行交互时不可或缺的资源,尤其在处理视频点播服务时。这些工具类提供了方便的方法,帮助开发者高效地完成各项任务,如设置区域、生成必要的安全参数以及进行签名验证。下面我们将深入探讨这些工具类的关键功能及其工作原理。
`AliyunVodSDKUtils.java` 文件很可能是包含了一系列与阿里云视频点播SDK相关的辅助方法。在阿里云的视频点播服务中,开发者需要指定服务的接入区域,因为阿里云的服务在全球范围内分布有多个可用区。`AliyunVodSDKUtils` 可能提供了设置和获取接入区域的函数,确保请求能够正确路由到对应的服务器。
描述中提到的“生成视频点播OpenAPI公共参数”,这涉及到API调用的基础构建块。通常,这些参数包括AccessKeyId、AccessKeySecret和Timestamp等,它们用于验证请求的来源和时间戳,防止重放攻击。`AliyunVodAPIUtils.java` 文件可能包含了生成这些参数的方法。
接着,关于“获取CQS”(Cloud Queue Service)的提及,CQS是阿里云提供的分布式消息队列服务。在视频点播场景下,CQS可能用于处理异步任务,如视频转码完成后通知应用。`AliyunVodSDKUtils` 或许包含了一些接口,允许开发者无缝集成CQS,以便在处理视频任务时实现消息的发送和接收。
然后,我们来谈谈“按照Base64编码规则把HMAC值编码成字符串”。在API调用的安全机制中,HMAC(Hash-based Message Authentication Code)是一种基于密钥的哈希函数,用于验证数据的完整性和来源。它通常结合AccessKeySecret计算出一个签名值,然后通过Base64编码转换为字符串形式,便于在网络上传输。`AliyunVodAPIUtils` 文件中应该包含生成HMAC和进行Base64编码的函数。
生成“签名值(Signature)”是确保请求安全的关键步骤。签名过程涉及到对请求参数和AccessKeySecret进行特定算法(如HMAC-SHA1或HMAC-SHA256)的哈希运算,然后将结果Base64编码。`AliyunVodAPIUtils` 文件会提供这样的功能,帮助开发者创建安全的API调用。
这两个工具类`AliyunVodSDKUtils.java` 和 `AliyunVodAPIUtils.java` 是为了简化阿里云视频点播服务的开发过程,它们封装了复杂的参数生成、签名计算以及与CQS等其他服务的交互逻辑,使得开发者可以更专注于业务逻辑,而不是底层通信细节。使用这些工具类,开发者可以更加便捷、安全地对接阿里云的各项服务,提高开发效率和应用稳定性。