赞
踩
这一篇,讲述了通过 阿里云API 进行动态修改 “域名解析” 服务的方法,附带完整源代码(包括阿里云SDK)可以直接编译运行。
附源码:源码
讨论QQ群: 296538273
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);
}
::返回到工程根目录下
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
黄色mark的地方是请求结果,红色方框是请求的API,至此获取、更新域名解析成功。
其他: 至于获取公网IP的办法,现在有很多,可以参考dtdns的源码里面有一个网址可以获取公网IP。
附源码:源码