这一篇,讲述了通过 阿里云API 进行动态修改 “域名解析” 服务的方法,附带完整源代码(包括阿里云SDK)可以直接编译运行。
附源码:源码
讨论QQ群: 296538273
1. 前期准备工作
- 1.1 访问 http://www.aliyun.com 创建AccessKey,如果已经有Key可以不用创建,AccessKey 是调用阿里API接口的一个身份验证。如下图所示:
1.2 下载SDK
访问 https://oss.sonatype.org/#nexus-search;gav~com.aliyun~aliyun-java-sdk-*~~~ 可以下载 SDK;
访问 https://github.com/aliyun/aliyun-openapi-java-sdk/ 下载最新 SDK 源码
个人感觉下载源码使用比较方便,因为源码里面有各种产品线 API 接口,可以自行提取裁剪,如下图所示:
其实我们只是用到了其中红色方框中的云解析、域名API,下载我的源码,里面已经提取了响应的API源码。
1.3 提取所用API源码如下图所示:
我们只用到了 alidns 和 core 2个库。
1.4 创建ddns工程如下:
2. 编写代码:
2.1 主要请求的代码在 com.ddns 包的 ddns.java中,具体实现步骤如下:
1) 首先,我们要知道若要更改自已的域名解析值需要获取到详细的域名解析记录;
2) 其次,找到我们需要更新的域名解析记录,进行更新操作;
注意: 阿里云的所有API请求都是标准的 Http 协议。// 1. 获取域名解析记录
// 通过查询API接口可以得到 Action public static String GetDomainRecords() { Map<String, String> parameters = GetPublicParams(); parameters.put("Action", "DescribeDomainRecords"); parameters.put("DomainName", "你的域名.com"); return GetRequestStr("GET", SERVER_URL, parameters); }
// 查询API文档可知除了 Action, DomainName的可变参数之外,还有一些公共固定参数如下:
// 这些是请求的固定参数 private static Map<String, String>GetPublicParams() { Map<String, String> parameters = new HashMap<String, String>(); // insert params parameters.put("Action", "DescribeDomainRecords"); parameters.put("DomainName", DOMAIN_NAME); parameters.put("AccessKeyId", ACCESS_KEY); parameters.put("Format", "JSON"); parameters.put("SignatureMethod", SIG_METHOD); parameters.put("SignatureVersion", SIG_VER); parameters.put("SignatureNonce", UUID.randomUUID().toString()); parameters.put("Timestamp", formatIso8601Date(new Date())); parameters.put("Version", ALIYUN_API_VER); return parameters; }
// 获取完整的 Http 请求 url
private static String GetRequestStr(String HttpMethod, String host, Map<String, String> params) { final String SEPARATOR = "&"; // param sort, Upper and Lower not equal String[] sortedKeys = params.keySet().toArray(new String[]{}); Arrays.sort(sortedKeys); // create stringToSign str StringBuilder stringToSign = new StringBuilder(); stringToSign.append(HttpMethod).append(SEPARATOR); try { stringToSign.append(percentEncode("/")).append(SEPARATOR); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } StringBuilder canonicalizedQueryString = new StringBuilder(); for(String key : sortedKeys) { // encode key, value try { canonicalizedQueryString.append(SEPARATOR) .append(percentEncode(key)).append("=") .append(percentEncode(params.get(key))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } // encode canonicalizedQueryString try { stringToSign.append(percentEncode(canonicalizedQueryString.toString(). substring(1))); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } String http_request = new String(); StringBuilder httpRequest = new StringBuilder(); try { String signature = GetSignature(stringToSign.toString()); httpRequest.append("http://"); httpRequest.append(host); httpRequest.append("/?"); httpRequest.append(canonicalizedQueryString.toString().substring(1)); httpRequest.append("&Signature="); httpRequest.append(percentEncode(signature)); } catch (Exception e) { e.printStackTrace(); } return httpRequest.toString(); }
// 生成阿里签名 [https://help.aliyun.com/document_detail/29747.html?spm=5176.doc29739.6.588.Ntca1z](API%E6%96%87%E6%A1%A3)
// 通过API文档可以查询具体的签名机制 private static String GetSignature(String stringToSign) { // signature test final String ALGORITHM = "HmacSHA1"; final String ENCODING = "UTF-8"; String key = ACCESS_SECRT + "&"; Mac mac = null; byte[] signData = null; try { mac = Mac.getInstance(ALGORITHM); mac.init(new SecretKeySpec( key.getBytes(ENCODING), ALGORITHM)); signData = mac.doFinal( stringToSign.getBytes(ENCODING)); } catch (Exception e) { e.printStackTrace(); } return new String(Base64.encodeBase64(signData)); }
// 先调用上述的GetDomainRecords(),再更新指定解析记录
// 更新某一条域名解析记录 public static String GetUpdateDomainRecord(String RecordID, String RR, String Type, String Value) { Map<String, String> parameters = GetPublicParams(); // insert params parameters.put("Action", "UpdateDomainRecord"); parameters.put("RecordId", RecordID); parameters.put("RR", RR); parameters.put("Type", Type); parameters.put("Value", Value); return GetRequestStr("GET", SERVER_URL, parameters); }
3. 编译代码:
::返回到工程根目录下
cd .
::创建bin文件夹
mkdir bin
::获取所有java文件绝对路径保存到src.list文件中
dir /b/s src\*.java > src.list
::用src.list编译java文件
javac -encoding UTF-8 -sourcepath src -d bin -classpath "lib/*;" @src.list
::运行
java -classpath "bin;lib/*;" com.ddns.ddns
4. 运行结果:
黄色mark的地方是请求结果,红色方框是请求的API,至此获取、更新域名解析成功。
其他: 至于获取公网IP的办法,现在有很多,可以参考dtdns的源码里面有一个网址可以获取公网IP。
附源码:源码