WebApi方式发送阿里云短信

linux命令行发送脚本

#!/usr/bin/env bash

# server
aliyunSmsServer="https://dysmsapi.aliyuncs.com"

#接收方手机号
PhoneNumbers="175211112222"
#签名
SignName="权益提醒"
#短信模板
TemplateCode="SMS_11112222"
#模板参数(json格式)
TemplateParam="{\"title\":\"测试标题\"}"

AccessKeyId="AccessKeyId"
accessSecret="accessSecret"

NONCE="`uuid`"
Timestamp="`date -u '+%Y-%m-%dT%H:%M:%SZ'`"
Root="/"

# urlencode
SignName="`/bin/echo -n "${SignName}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"
TemplateParam="`/bin/echo -n "${TemplateParam}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"
Timestamp="`/bin/echo -n "${Timestamp}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"
RootToSign="`/bin/echo -n "${Root}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-`"

sortedQueryString="AccessKeyId=${AccessKeyId}&Action=SendSms&Format=JSON&PhoneNumbers=${PhoneNumbers}&SignName=${SignName}&SignatureMethod=HMAC-SHA256&SignatureNonce=${NONCE}&SignatureVersion=1.0&TemplateCode=${TemplateCode}&TemplateParam=${TemplateParam}&Timestamp=${Timestamp}&Version=2017-05-25"

echo "sortedQueryString = ${sortedQueryString}"

# urlencode
sortedQueryStringToSign="`/bin/echo -n "${sortedQueryString}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3- | sed 's/\+/%20/g' | sed 's/\*/%2A/g' | sed 's/%7E/~/g'`"
echo "sortedQueryStringToSign = ${sortedQueryStringToSign}"

stringToSign="GET&${RootToSign}&${sortedQueryStringToSign}"
echo "stringToSign = ${stringToSign}"

sign="`/bin/echo -n "${stringToSign}" | openssl dgst -sha256 -hmac "${accessSecret}&" -binary | base64`"
signature="`/bin/echo -n "${sign}" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3- | sed 's/\+/%20/g' | sed 's/\*/%2A/g' | sed 's/%7E/~/g'`"

url="${aliyunSmsServer}/?Signature=${signature}&${sortedQueryString}"
echo "${url}"

curl -v "${url}"

echo ""

Java-RestTemplate方式发送短信

@Configuration
public class AliyunSmsConfig {

    public static void main1(String[] args) throws Exception {
        /**
         * 测试阿里云短信SDK发送
         */
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config().setAccessKeyId("accessKeyId").setAccessKeySecret("accessSecret").setProtocol(ProtocolType.HTTP);
        config.endpoint = "dysmsapi.aliyuncs.com";
        Client client = new Client(config);

        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions().setHttpProxy("http://127.0.0.1:8888").setHttpsProxy("http://127.0.0.1:8888").setAutoretry(true).setMaxAttempts(3);

        com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                .setSignName("权益提醒")//签名
                .setTemplateCode("SMS_11112222")//模板code
                .setPhoneNumbers("17511112222")//手机号
                .setTemplateParam("{\"title\":\"测试标题\"}");//模板参数
        com.aliyun.dysmsapi20170525.models.SendSmsResponse resp = client.sendSmsWithOptions(sendSmsRequest, runtime);

        System.out.println("测试发送短信,返回结果");
        System.out.println(JSONObject.toJSONString(resp));
    }

    public static void main(String[] args) throws Exception {
        /**
         * 测试阿里云短信WebApi发送
         */
        java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT"));// 这里一定要设置GMT时区

        String accessKeyId = "accessKeyId";
        String accessSecret = "accessSecret";
        String endpoint = "https://dysmsapi.aliyuncs.com";
        String PhoneNumbers = "17511112222";
        String SignName = "权益提醒";
        String TemplateCode = "SMS_111122227";
        String TemplateParam = "{\"title\":\"测试标题\"}";


        java.util.Map<String, String> paras = new java.util.HashMap<String, String>();
        // 1. 系统参数
        paras.put("SignatureMethod", "HMAC-SHA256");
        paras.put("SignatureNonce", java.util.UUID.randomUUID().toString());
        paras.put("AccessKeyId", accessKeyId);
        paras.put("SignatureVersion", "1.0");
        paras.put("Timestamp", df.format(new java.util.Date()));
        paras.put("Format", "JSON");
        // 2. 业务API参数
        paras.put("Action", "SendSms");
        paras.put("Version", "2017-05-25");
        paras.put("RegionId", "");
        paras.put("PhoneNumbers", PhoneNumbers);
        paras.put("SignName", SignName);
        paras.put("TemplateParam", TemplateParam);
        paras.put("TemplateCode", TemplateCode);
        // 3. 去除签名关键字Key
        if (paras.containsKey("Signature"))
            paras.remove("Signature");
        // 4. 参数KEY排序
        java.util.TreeMap<String, String> sortParas = new java.util.TreeMap<String, String>();
        sortParas.putAll(paras);
        // 5. 构造待签名的字符串
        java.util.Iterator<String> it = sortParas.keySet().iterator();
        StringBuilder sortQueryStringTmp = new StringBuilder();
        while (it.hasNext()) {
            String key = it.next();
            sortQueryStringTmp.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(paras.get(key)));
        }
        String sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号
        StringBuilder stringToSign = new StringBuilder();
        stringToSign.append("GET").append("&");
        stringToSign.append(specialUrlEncode("/")).append("&");
        stringToSign.append(specialUrlEncode(sortedQueryString));
        String sign = sign(accessSecret + "&", stringToSign.toString());
        // 6. 签名最后也要做特殊URL编码
        String signature = specialUrlEncode(sign);
        
        //7.请求
        String url = endpoint + "/?Signature=" + signature + sortQueryStringTmp;
// 最终打印出合法GET请求的URL
        System.out.println(endpoint + "/?Signature=" + signature + sortQueryStringTmp);
        RestTemplate restTemplate = endpoint.startsWith("https") ? new RestTemplate(new HttpsClientRequestFactory()) : new RestTemplate();
        String data = restTemplate.getForObject(new URI(url), String.class);
        System.out.println("阿里短信 By Web API sendSMS return = response.getData :" + data);
    }

    private static String specialUrlEncode(String value) throws Exception {
        return java.net.URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
    }

    private static String sign(String accessSecret, String stringToSign) throws Exception {
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA256");
        mac.init(new javax.crypto.spec.SecretKeySpec(accessSecret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        return new sun.misc.BASE64Encoder().encode(signData);
    }

    public static class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
        @Override
        protected void prepareConnection(HttpURLConnection connection, String httpMethod) {
            try {
                if (!(connection instanceof HttpsURLConnection)) {
                    throw new RuntimeException("An instance of HttpsURLConnection is expected");
                }

                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
                TrustManager[] trustAllCerts = new TrustManager[]{
                        new X509TrustManager() {
                            @Override
                            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                return null;
                            }
                            @Override
                            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                            }
                            @Override
                            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                            }
                        }
                };
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
                httpsConnection.setSSLSocketFactory(new MyCustomSSLSocketFactory(sslContext.getSocketFactory()));

                httpsConnection.setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String s, SSLSession sslSession) {
                        return true;
                    }
                });

                super.prepareConnection(httpsConnection, httpMethod);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        private static class MyCustomSSLSocketFactory extends SSLSocketFactory {
            private final SSLSocketFactory delegate;
            public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {
                this.delegate = delegate;
            }

            // 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。
            // 这些默认的服务的最低质量要求保密保护和服务器身份验证
            @Override
            public String[] getDefaultCipherSuites() {
                return delegate.getDefaultCipherSuites();
            }

            // 返回的密码套件可用于SSL连接启用的名字
            @Override
            public String[] getSupportedCipherSuites() {
                return delegate.getSupportedCipherSuites();
            }

            @Override
            public Socket createSocket(final Socket socket, final String host, final int port,
                                       final boolean autoClose) throws IOException {
                final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose);
                return overrideProtocol(underlyingSocket);
            }

            @Override
            public Socket createSocket(final String host, final int port) throws IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port);
                return overrideProtocol(underlyingSocket);
            }

            @Override
            public Socket createSocket(final String host, final int port, final InetAddress localAddress,
                                       final int localPort) throws
                    IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
                return overrideProtocol(underlyingSocket);
            }

            @Override
            public Socket createSocket(final InetAddress host, final int port) throws IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port);
                return overrideProtocol(underlyingSocket);
            }

            @Override
            public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress,
                                       final int localPort) throws
                    IOException {
                final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
                return overrideProtocol(underlyingSocket);
            }

            private Socket overrideProtocol(final Socket socket) {
                if (!(socket instanceof SSLSocket)) {
                    throw new RuntimeException("An instance of SSLSocket is expected");
                }
                //((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
                ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"});
                return socket;
            }
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值