本文提供使用Java语言构造参数和签名并POST发送请求的示例,其他语言流程类似。
CommonRequest调用使用示例
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
/**
* Demo所需依赖为Alibaba Cloud SDK for Java。
* 您可以通过直接添加Maven依赖或者下载Alibaba Cloud SDK for Java的开发工具包的方式安装Alibaba Cloud SDK for Java。
*
* 本Demo为泛用型的RPC风格的API调用方式。
* 使用CommonRequest调用方式可实现任意OpenAPI接口的调用。
* Demo调用了消息队列Kafka版的GetTopicList(获取Topic信息)接口。
*/
public class CommonRequestDemo {
// 购买的实例所在RegionId。
private static final String REGION_ID = "cn-huhehaote";
// 您的AccessKey ID。
private static final String ACCESS_KEY = "LTAI5tHRxaQd8WeJvDFZ****";
// 您的AccessKey Secret。
private static final String ACCESS_KEY_SECRET = "R1WUTHmTDlCy7J8csQ6bRnaMkY****";
// 实例所在服务地域。
private static final String SYS_DO_MAIN = "alikafka.cn-huhehaote.aliyuncs.com";
public static void main(String[] args) {
// 创建DefaultAcsClient实例并初始化
DefaultProfile profile = DefaultProfile.getProfile(
REGION_ID, // 您的地域ID。
ACCESS_KEY, // 您的AccessKey ID。
ACCESS_KEY_SECRET); // 您的AccessKey Secret。
IAcsClient client = new DefaultAcsClient(profile);
// 创建API请求并设置参数。
CommonRequest request = new CommonRequest();
// 实例所在服务地域。
request.setSysDomain(SYS_DO_MAIN);
// API版本。
request.setSysVersion("2019-09-16");
// 接口名称。
request.setSysAction("GetTopicList");
// 接口参数。
request.putQueryParameter("InstanceId", "alikafka_pre-cn-tl32d052****");
request.putQueryParameter("PageNumber", "1");
request.putQueryParameter("PageSize", "30");
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
} catch (ClientException e) {
e.printStackTrace();
}
}
}
HTTP调用使用示例
private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final String ENCODING = "UTF-8";
private static final String HTTP_METHOD = "POST";
// 消息队列Kafka版实例的地域的Region ID。
private static final String REGION_ID = "cn-xxxxxx";
private static final String ACCESS_KEY = "xxxxxx";
private static final String ACCESS_KEY_SECRET = "xxxxxx";
public static void main(String[] args) {
try {
// 1. 设置参数。
Map<String, String> parameters = buildCommonParams();
// 2. 排序请求参数: 根据字母排序。
String[] sortedKeys = sortParamsToArray(parameters);
// 3. 构造stringToSign字符串。
String stringToSign = buildSignString(parameters, sortedKeys);
// 4. 计算签名。
String signature = calculateSignature(stringToSign);
// 5. 将签名设置到参数中。
parameters.put("Signature", signature);
// 6. 发送POST请求。
String result = post(String.format("http://alikafka.%s.aliyuncs.com/", REGION_ID), parameters);
// 7. 验证结果。
System.out.println(result);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
private static Map<String, String> buildCommonParams() {
Map<String, String> parameters = Maps.newHashMap();
// Action为请求方法。
// GetInstanceList:获取实例信息;GetConsumerList:获取消费组列表;GetTopicList:获取Topic列表;GetTopicStatus:获取 Topic 状态。
// GetConsumerProgress:获取消费状态;CreateTopic:创建Topic;CreateConsumerGroup:创建Group。
parameters.put("Action", "GetInstanceList");
// 接口版本:"2018-10-15"。
parameters.put("Version", "2018-10-15");
// 请求参数:RegionId为必填参数。
// 如果接口有其他参数请都设置:比如 InstanceId/Topic/ConsumerId。
// parameters.put("InstanceId", "cn-huhehaote");
// parameters.put("Topic", "cn-huhehaote");
// parameters.put("Remark", "cn-huhehaote");
// parameters.put("ConsumerId", "cn-huhehaote");
parameters.put("RegionId", REGION_ID);
parameters.put("AccessKeyId", ACCESS_KEY);
// 时间戳,注意格式:yyyy-MM-dd'T'HH:mm:ss'Z'。
parameters.put("Timestamp", formatIso8601Date(new Date()));
parameters.put("SignatureMethod", "HMAC-SHA1");
parameters.put("SignatureVersion", "1.0");
parameters.put("SignatureNonce", UUID.randomUUID().toString());
parameters.put("Format", "json");
return parameters;
}
private static String[] sortParamsToArray(Map<String, String> parameters) {
String[] sortedKeys = parameters.keySet().toArray(new String[]{});
Arrays.sort(sortedKeys);
return sortedKeys;
}
private static String buildSignString(Map<String, String> parameters,
String[] sortedKeys) throws UnsupportedEncodingException {
StringBuilder stringToSign = new StringBuilder();
String SEPARATOR = "&";
stringToSign.append(HTTP_METHOD).append(SEPARATOR);
stringToSign.append(percentEncode("/")).append(SEPARATOR);
StringBuilder canonicalizedQueryString = new StringBuilder();
for(String key : sortedKeys) {
// 注意编码key和value。
canonicalizedQueryString.append("&")
.append(percentEncode(key)).append("=")
.append(percentEncode(parameters.get(key)));
}
// 注意编码canonicalizedQueryString。
stringToSign.append(percentEncode(canonicalizedQueryString.toString().substring(1)));
return stringToSign.toString();
}
private static String calculateSignature(String stringToSign)
throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
String ALGORITHM = "HmacSHA1";
String ENCODING = "UTF-8";
// 对应账号的AccessKeySecret。
String accessKeySecret = ACCESS_KEY_SECRET + "&";
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(accessKeySecret.getBytes(ENCODING), ALGORITHM));
byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING));
return new String(Base64.getEncoder().encode(signData));
}
private static String percentEncode(String value) throws UnsupportedEncodingException {
return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
}
private static String formatIso8601Date(Date date) {
SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
df.setTimeZone(new SimpleTimeZone(0, "GMT"));
return df.format(date);
}
private static String post(String url, Map<String, String> paramMap) throws IOException {
Form form = Form.form();
for (String key : paramMap.keySet()) {
form.add(key, paramMap.get(key));
}
return Request.Post(url).bodyForm(form.build()).connectTimeout(10000).execute().returnContent().asString();
}