利用新版本阿里云API实现动态域名解析

版权声明:可以随意转载反正又写不出什么核心技术 但转载请注明出处 https://blog.csdn.net/My_dearest_/article/details/82558680

利用阿里云提供的云解析服务API完成动态域名解析。

所用到的阿里云API版本参照https://help.aliyun.com/document_detail/29821.html

<repositories>
        <repository>
            <id>sonatype-nexus-staging</id>
            <name>Sonatype Nexus Staging</name>
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
</repositories>
添加jar包依赖

<dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>aliyun-java-sdk-alidns</artifactId>
      <version>2.0.1</version>
</dependency>
<dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>aliyun-java-sdk-core</artifactId>
      <version>2.3.8</version>
</dependency>

整个服务分为以下四个模块:

1、获取外部IP。可以是通过某个URL请求或者模拟在百度搜索“IP”,再通过正则抓取返回信息中的IP信息。

2、解析域名。

3、定时任务。阿里云提供的免费云解析TTL = 600s,服务商可能每天或者几天进行一次动态IP的分配,由于一次生效后有效时间较长,中间只需要对比目前的外网IP与上一次解析到的IP是否一致即可。这里可以利用while(true)+Thread.sleep完成,也可以利用Timer等完成。

4、log4j2日志处理。

这里只贴一下1、2部分的代码:

获取外部IP:

​
package com.shinoha.ddns;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IPService{
	//百度应该是最稳定的获取IP的方法之一了
	//必要参数,否则百度不会返回正常数据
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) 
		AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36";

    public static String getOutSideIP(){
        try{
            String reqUrl = "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=ip";
            URL url = new URL(reqUrl);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setConnectTimeout(5000);
            setReqProperty(connection);
            int responseCode = connection.getResponseCode();
            if(responseCode != 200){
                throw new Exception("connection error : "+responseCode+"");
            }
            InputStream is = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is , StandardCharsets.UTF_8));
            StringBuilder responseContent = new StringBuilder();
            String line;
			//这里或许逐行执行正则匹配,成功立即返回,可能效率更高一点
            while((line = reader.readLine()) != null){
                line += "\r\n";
                responseContent.append(line);
            }
            String regex = "本机IP:&nbsp;([\\S]+?)</span>";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(responseContent);
            if(matcher.find()){
                return matcher.group(1);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return "error";
    }

    private static void setReqProperty(HttpURLConnection connection){
        connection.setRequestProperty("Accept-Charset", "utf-8");
        connection.setRequestProperty("Accept" ,"text/html,application/xhtml+xml,
			application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        connection.setRequestProperty("User-Agent" ,USER_AGENT);
        connection.setRequestProperty("Connection" ,"keep-alive");
    }
}

​

执行动态解析:

​
package com.shinoha.ddns;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.*;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsResponse.Record;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;

import java.util.List;

public class DynamicDNS {
	//待解析的域名
    private static final String TARGET_DOMAIN = "Your Domain";
	//用来发送各种请求
    private static IAcsClient client;
    static {
		//根据阿里云SDK文档,云解析时这个参数只能为"cn-hangzhou"
        String regionId = "cn-hangzhou";
        String accessKeyId = "Your accessKeyId";
        String accessKeySecret = "Your accessKeySecret";
        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        client = new DefaultAcsClient(profile);
    }

    /**
     * @return 是否解析成功 1 = ok ,-1 = 获取外网ip错误,-2 = 通过阿里云API解析时错误
     */
    public static int parsingDNS(String outSideIP){
		//将拿到的外部IP传入这里
        if(outSideIP.equals("error")){
            return -1;
        }
        DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
		//必要参数,指定目标域名
        request.setDomainName(TARGET_DOMAIN);
        DescribeDomainRecordsResponse response;
        try{
            response = client.getAcsResponse(request);
			//实际上前边的request.setDomainName(TARGET_DOMAIN)完整无误的话这里的list的长度就是1
            List<Record> list = response.getDomainRecords();
            String recordID = null;
            for(Record record : list){
                if(record.getDomainName().equals(TARGET_DOMAIN)){
                    recordID = record.getRecordId();//拿到待解析域名的RecordID,后边是必须参数
                }
            }
            UpdateDomainRecordRequest updateReq = new UpdateDomainRecordRequest();
            updateReq.setActionName("UpdateDomainRecord");//更新解析只能为UpdateDomainRecord,必填
            updateReq.setValue(outSideIP);//解析记录值
            updateReq.setRecordId(recordID);//在前边通过response.getDomainRecords()拿到
            updateReq.setType("A");//解析类型
            updateReq.setTTL(600L);//TTL,免费版最小值为600
            updateReq.setRR("@");//主机记录
            client.getAcsResponse(updateReq);//发送请求.在返回中好像拿不到ErrorCode一类的东西了,出错是直接抛出异常
            return 1;
        }catch (ClientException e){
            e.printStackTrace();
            Loggers.info(e.getCause()+" "+e.getMessage());
            return -2;
        }
    }

	//获取当前解析记录,程序初始化时可能有用
    public static String getCurrentDNSVal() {
        DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
        request.setDomainName(TARGET_DOMAIN);
        DescribeDomainRecordsResponse response;
        try {
            response = client.getAcsResponse(request);
            List<Record> list = response.getDomainRecords();
            for (Record record : list) {
                if (record.getDomainName().equals(TARGET_DOMAIN)) {
                    return record.getValue();
                }
            }
        } catch (ClientException e) {
            e.printStackTrace();
            Loggers.info(e.getCause() + " " + e.getMessage());
        }
        return "0.0.0.0";
    }
}

​

猜你喜欢

转载自blog.csdn.net/My_dearest_/article/details/82558680