This topic describes how to construct parameters and a signature in Java and then send a POST request. The procedure in other programming languages is similar.

CommonRequest call examples

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;

/**
 * The required dependency for this demo is Alibaba Cloud SDK for Java. 
 * You can install Alibaba Cloud SDK for Java by adding Maven dependencies or downloading Alibaba Cloud SDK for Java. 
 *
 * This demo is a generic Remote Procedure Call (RPC) method. 
 You can use CommonRequest to call API operations. 
 * This demo calls the GetTopicList operation of Message Queue for Apache Kafka to query topics. 

 */
public class CommonRequestDemo {

    // The region ID of your purchased instance. 
    private static final String REGION_ID = "cn-huhehaote";
    // Your AccessKey ID. 
    private static final String ACCESS_KEY = "LTAI5tHRxaQd8WeJvDFZ****";
    // Your AccessKey secret. 
    private static final String ACCESS_KEY_SECRET = "R1WUTHmTDlCy7J8csQ6bRnaMkY****";
    // The region where the instance is deployed. 
    private static final String SYS_DO_MAIN = "alikafka.cn-huhehaote.aliyuncs.com";

    public static void main(String[] args) {
        // Create a DefaultAcsClient instance and initialize the instance.
        DefaultProfile profile = DefaultProfile.getProfile(
                REGION_ID,          // Your region ID. 
                ACCESS_KEY,         // Your AccessKey ID. 
                ACCESS_KEY_SECRET); // Your AccessKey secret. 
        IAcsClient client = new DefaultAcsClient(profile);
        // Create an API request and configure the parameters. 
        CommonRequest request = new CommonRequest();
        // The region where the instance is deployed. 
        request.setSysDomain(SYS_DO_MAIN);
        // The version number of the API. 
        request.setSysVersion("2019-09-16");
        // The name of the operation. 
        request.setSysAction("GetTopicList");
        // The parameters of the operation. 
        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 call examples

  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";
    // The ID of the region where the Message Queue for Apache Kafka instance is deployed. 
    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. Set parameters. 
            Map<String, String> parameters = buildCommonParams();
            // 2. Sort request parameters in alphabetical order. 
            String[] sortedKeys = sortParamsToArray(parameters);
            // 3. Create a string-to-sign. 
            String stringToSign = buildSignString(parameters, sortedKeys);
            // 4. Calculate the signature. 
            String signature = calculateSignature(stringToSign);
            // 5. Add the signature string to the request as a parameter. 
            parameters.put("Signature", signature);
            // 6. Send the POST request. 
            String result = post(String.format("http://alikafka.%s.aliyuncs.com/", REGION_ID), parameters);
            // 7. Verify the result. 
            System.out.println(result);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }

    private static Map<String, String> buildCommonParams() {
        Map<String, String> parameters = Maps.newHashMap();
        // Action: specifies the request method. 
        // GetInstanceList: queries instances. GetConsumerList: queries consumer groups. GetTopicList: queries topics. GetTopicStatus: queries the status of a topic. 
        // GetConsumerProgress: queries the status of a consumer group. CreateTopic: creates a topic. CreateConsumerGroup: creates a Group. 
        parameters.put("Action", "GetInstanceList");
        // API version: "2018-10-15". 
        parameters.put("Version", "2018-10-15");
        // Request parameters: RegionId is a required parameter. 
        // Ensure that all the parameters of the API operation are specified, such as InstanceId, Topic, and 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);
        // Timestamp, in the format of 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) {
            // Encode the key and value. 
            canonicalizedQueryString.append("&")
                .append(percentEncode(key)).append("=")
                .append(percentEncode(parameters.get(key)));
        }

        // Encode the canonicalized query string. 
        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";
        // The AccessKey secret of the account. 
        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();
    }