阿里雲CDN刷新預熱接口


阿里雲OSS映射的文件地址需要即時訪問到最新數據,需要即時調用CDN的刷新預熱類接口 RefreshObjectCaches 刷新接口。

參考官方接口文檔資料:https://help.aliyun.com/document_detail/27200.html?spm=5176.doc27149.6.174.rsPZgC

官方接口調用方式(簽名):https://help.aliyun.com/document_detail/27149.html?spm=5176.doc27200.6.154.ldVcDB

直接上代碼:

package com.lwj.util.aliyuncdn;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SimpleTimeZone;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.lwj.util.aliyunoss.AliyunOssServerInfo;

import sun.misc.BASE64Encoder;

/**
 * 
 * @Description :阿里雲OSS服務器CDN刷新緩存
 * @author : liwenjian
 * @version : 1.0
 * @Date : 2016年8月22日 上午9:37:47
 */
public class AliyunCdnUtils {

    private static final String cdn_server_address = "https://cdn.aliyuncs.com";

    /**
     * 刷新緩存
     * 
     * @param objectPath
     * @return
     */
    public static String refreshObjectCaches(String objectPath) {
        // Map<String, String> param = new TreeMap<String, String>();
        // param.put("Action", "RefreshObjectCaches");
        // param.put("ObjectPath",
        // "http://b1.goimg.cn/test/images/1471590829296.png");
        // param.put("ObjectType", "File");
        AliyunCdnUtils cdn = new AliyunCdnUtils();
        Map<String, String> param = new TreeMap<String, String>();
        param.put("Action", "RefreshObjectCaches");
        param.put("ObjectPath", objectPath);
        param.put("ObjectType", "File");
        String url = cdn.compose_url(param);
        System.out.println("Aliyun CDN RefreshObjectCaches Request Url:" + url);
        HttpClient client = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, Charset.forName("UTF-8"));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 組合請求路徑
     * 
     * @param user_params
     * @return
     */
    private String compose_url(Map<String, String> user_params) {
        // 請求的時間戳。日期格式按照ISO8601標准表示,並需要使用UTC時間。格式為:YYYY-MM-DDThh:mm:ssZ。
        // 例如,2014-11-11T12:00:00Z(為北京時間2014年11月11日20點0分0秒)
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd'T'hh:mm:ss'Z'");
        sdf.setTimeZone(new SimpleTimeZone(0, "GMT"));
        String timestamp = sdf.format(new Date());
        Map<String, String> parameters = new TreeMap<String, String>();
        parameters.put("Format", "JSON");
        parameters.put("Version", "2014-11-11");
        parameters.put("AccessKeyId", AliyunOssServerInfo.getAccessKeyId().trim());
        parameters.put("SignatureVersion", "1.0");
        parameters.put("SignatureMethod", "HMAC-SHA1");
        parameters.put("SignatureNonce", String.valueOf(System.currentTimeMillis()));
        parameters.put("TimeStamp", timestamp);
        // 添加用戶請求參數到簽名map中
        Iterator<Entry<String, String>> iterator = user_params.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, String> entry = iterator.next();
            parameters.put(entry.getKey(), entry.getValue());
        }
        String signature = compute_signature(parameters, AliyunOssServerInfo.getAccessKeySecret());
        parameters.put("Signature", signature);
        return cdn_server_address + "/?" + map_to_url(parameters);
    }

    /**
     * 計算簽名
     * 
     * @param parameters
     * @param access_key_secret
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    private String compute_signature(Map<String, String> parameters, String access_key_secret) {
        try {
            StringBuilder canonicalizedQueryString = new StringBuilder();
            // 調用Map進行字典排序
            parameters = sortMap(parameters);
            // 一、按照參數名稱的字典順序對請求中所有的請求參數(包括文檔中描述的“公共請求參數”和給定了的請求接口的自定義參數,但不能包括“公共請求參數”中提到Signature參數本身)進行排序。
            // 遍歷組合組合簽名
            Iterator<Entry<String, String>> iterator = parameters.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<String, String> entry = iterator.next();
                // 對Map鍵值對進行URL編碼
                // 二、對每個請求參數的名稱和值進行編碼。名稱和值要使用UTF-8字符集進行URL編碼,URL編碼的編碼規則是:
                // (1)對於字符 A-Z、a-z、0-9以及字符“-”、“_”、“.”、“~”不編碼;
                // (2)對於其他字符編碼成“%XY”的格式,其中XY是字符對應ASCII碼的16進制表示。比如英文的雙引號(”)對應的編碼就是%22
                // (3)對於擴展的UTF-8字符,編碼成“%XY%ZA…”的格式;
                // (4)需要說明的是英文空格( )要被編碼是%20,而不是加號(+)。
                canonicalizedQueryString.append("&").append(percent_encode(entry.getKey())).append("=")
                        .append(percent_encode(entry.getValue()));
            }
            // 三、調用percent_encode方法把編碼后的字符串中加號(+)替換成%20、星號(*)替換成%2A、%7E替換回波浪號(~)
            String stringToSign = "GET&%2F&" + percent_encode(canonicalizedQueryString.toString().substring(1).trim());
            // 按照RFC2104的定義,使用上面的用於簽名的字符串計算簽名HMAC值。注意:計算簽名時使用的Key就是用戶持有的Access
            // Key Secret並加上一個“&”字符(ASCII:38),使用的哈希算法是SHA1
            String key = AliyunOssServerInfo.getAccessKeySecret() + "&";
            SecretKey secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(secretKey);
            byte[] sign = mac.doFinal(stringToSign.getBytes());
            System.out.println("stringToSign:" + stringToSign);
            // 得到簽名
            String signature = (new BASE64Encoder()).encode(sign);
            System.out.println("signature:" + signature);
            return percent_encode(signature);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * map轉為請求URL
     * 
     * @param parameters
     * @return
     */
    private String map_to_url(Map<String, String> parameters) {
        try {
            parameters = sortMap(parameters);
            StringBuilder url = new StringBuilder();
            Iterator<Entry<String, String>> iterator = parameters.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<String, String> entry = iterator.next();
                url.append("&").append(entry.getKey()).append("=").append(entry.getValue());
            }
            return url.toString().substring(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 轉換特殊字符
     * 
     * @param param
     * @return
     */
    private String percent_encode(String param) {
        try {
            // 名稱和值要使用UTF-8字符集進行URL編碼
            param = URLEncoder.encode(param, "UTF-8");
            param = param.replaceAll("\\+", "%20");
            param = param.replaceAll("\\*", "%2A");
            param = param.replaceAll("%7E", "~");
            return param;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Map排序
     * 
     * @param parameters
     * @return
     */
    private Map<String, String> sortMap(Map<String, String> parameters) {
        if (parameters.isEmpty()) {
            return null;
        }
        // 按字典排序
        Map<String, String> sortMap = new TreeMap<String, String>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                // 指定排序器按照降序排列
                // return o2.compareTo(o1);
                // 指定排序器按照升序序排列
                return o1.compareTo(o2);
            }
        });
        sortMap.putAll(parameters);
        return sortMap;
    }

    public static void main(String[] args) {
        AliyunCdnUtils a = new AliyunCdnUtils();
        Map<String, String> param = new TreeMap<String, String>();
        param.put("Action", "RefreshObjectCaches");
        param.put("ObjectPath", "http://b1.goimg.cn/test/images/1471590829296.png");
        param.put("ObjectType", "File");
        String url = a.compose_url(param);
        System.out.println("request url:" + url);
        HttpClient client = HttpClients.createDefault();
        HttpGet httpgets = new HttpGet(url);
        try {
            HttpResponse response = client.execute(httpgets);
            HttpEntity entity = response.getEntity();
            System.out.println(EntityUtils.toString(entity, Charset.forName("UTF-8")));
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

成功提示:

{"RefreshTaskId":"466571432","RequestId":"1F401222-FA52-4F26-B9C2-1CFDEEA58DAB"}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM