华为云短信,超详细,从官网开始

所需的官方文档

开头先放所需的官方文档的链接汇总,方便查看,下面用到时也会重新放。

  1. https://support.huaweicloud.com/devg-apisign/api-sign-sdk-java.html
    在这里插入图片描述
  2. https://support.huaweicloud.com/api-msgsms/sms_05_0001.html
    发送短信的api接口文档(可查看错误码)
  3. https://support.huaweicloud.com/devg-msgsms/sms_04_0018.html
    发送短信代码示例(截止到24年8月初,华为云官方公告没有发送短信的sdk,所以只能看这个)
  4. https://support.huaweicloud.com/productdesc-msgsms/sms_faq_0003.html
    短信变量规范
  5. https://console.huaweicloud.com/apiexplorer/#/openapi/MSGSMS/doc?api=CreateTemplate
    在线调试,但目前上面只有应用,签名,模板

数据准备

先登录华为云准备以下数据(签名审核时间较长,3个工作日以内;另外华为云想发通知类型短信验证码类型短信需要两个不同的签名;阿里云是一个签名通用)

截图网页来源:https://support.huaweicloud.com/devg-msgsms/sms_04_0006.html

发送短信

public class HuaweiyunSendSms {


    static final String url = "";
    static final String appKey = "";
    static final String appSecret = "";
    //通知类签名通道号
    static final String senderNotice = "";
    //验证码类签名通道号
    static final String senderCode = "";
    //签名名称
    static final String signature = "";

    private static final Logger LOGGER = LoggerFactory.getLogger(HuaweiyunSendSms.class);

    public static final String UTF_8 = "UTF-8";

    private static CloseableHttpClient client = null;

    /*public static void main(String[] args) throws Exception {
        // 为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
        client = createIgnoreSSLHttpClient();
        sendSms();
    }*/

    /**
     * 调用短信
     * @param receiver 接收短信手机号
     * @param sender 中国大陆短信签名通道号或全球短信通道号
     * @param signature 签名名称
     * @param templateId  模板ID
     * @param templateParas  模板参数
     * @throws Exception
     * @return s 发送短信的结果
     */
    private static String sendSms(String receiver, String sender, String signature, String templateId, String templateParas) throws Exception {
        receiver = "+86" + receiver;
        //源头传的是阿里云的param,所以这里处理成华为云的
        /*templateParas = HwyTemplate.getHwyParamsById(templateId,templateParas);
        templateParas = HwyTemplate.updateHwyParams(templateParas);*/
        client = createIgnoreSSLHttpClient();
        /*//必填,请参考"开发准备"获取如下数据,替换为实际值
        String url = "https://smsapi.cn-north-4.myhuaweicloud.com:443/sms/batchSendSms/v1"; //APP接入地址+接口访问URI
        // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
        String appKey = "c8RWg3gg************3Y7x1Ile"; //Application Key
        String appSecret = "q4Ii87Bh************80SfD7Al"; //Application Secret*/
        /*String sender = "csms12345678"; //中国大陆短信签名通道号或全球短信通道号
        String templateId = "8ff55eac1d0b478ab3c06c3c6a492300"; //模板ID

        //条件必填,中国大陆短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称
        //全球短信不用关注该参数
        String signature = "华为云短信测试"; //签名名称

        //必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔
        String receiver = "+86151****6789,+86152****7890"; //短信接收人号码*/

        //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告
        String statusCallBack = "";

        /**
         * 选填,使用无变量模板时请赋空值 String templateParas = "";
         * 单变量模板示例:模板内容为"您的验证码是${NUM_6}"时,templateParas可填写为"[\"111111\"]"
         * 双变量模板示例:模板内容为"您有${NUM_2}件快递请到${TXT_20}领取"时,templateParas可填写为"[\"3\",\"人民公园正门\"]"
         * 查看更多模板规范和变量规范:产品介绍>短信模板须知和短信变量须知
         */
/*
        String templateParas = "[\"111111\"]"; //模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。
*/

        //请求Body,不携带签名名称时,signature请填null
        String body = buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, signature);
        if (null == body || body.isEmpty()) {
            LOGGER.warn("body is null.");
            return null;
        }

        Request request = new Request();
        request.setKey(appKey);
        request.setSecret(appSecret);
        request.setMethod("POST");
        request.setUrl(url);
        request.addHeader("Content-Type", "application/x-www-form-urlencoded");
        request.setBody(body);
        LOGGER.info("Print the body: {}", body);

        try {
            HttpRequestBase signedRequest = Client.sign(request, "SDK-HMAC-SHA256");
            LOGGER.info("Print the authorization: {}", Arrays.toString(signedRequest.getHeaders("Authorization")));
            Header[] requestAllHeaders = signedRequest.getAllHeaders();
            for (Header h : requestAllHeaders) {
                LOGGER.info("req Header with name: {} and value: {}", h.getName(), h.getValue());
            }

            HttpResponse response = client.execute(signedRequest);

            LOGGER.info("Print the status line of the response: {}", response.getStatusLine().toString());
            Header[] resHeaders = response.getAllHeaders();
            for (Header h : resHeaders) {
                LOGGER.info("Processing Header with name: {} and value: {}", h.getName(), h.getValue());
            }
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                String s = EntityUtils.toString(resEntity, "UTF-8");
                LOGGER.info("Processing Body with name: {} and value: {}", System.getProperty("line.separator"),
                        s);
                return s;
            }
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
        return null;
    }

    public static CloseableHttpClient createIgnoreSSLHttpClient() throws Exception {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (x509CertChain, authType) -> true).build();
        return HttpClients.custom().setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)).build();
    }

    static String buildRequestBody(String sender, String receiver, String templateId, String templateParas,
                                   String statusCallBack, String signature) throws UnsupportedEncodingException {
        if (null == sender || null == receiver || null == templateId || sender.isEmpty() || receiver.isEmpty()
                || templateId.isEmpty()) {
            System.out.println("buildRequestBody(): sender, receiver or templateId is null.");
            return null;
        }

        StringBuilder body = new StringBuilder();
        appendToBody(body, "from=", sender);
        appendToBody(body, "&to=", receiver);
        appendToBody(body, "&templateId=", templateId);
        appendToBody(body, "&templateParas=", templateParas);
        appendToBody(body, "&statusCallback=", statusCallBack);
        appendToBody(body, "&signature=", signature);
        return body.toString();
    }

    private static void appendToBody(StringBuilder body, String key, String val) throws UnsupportedEncodingException {
        if (null != val && !val.isEmpty()) {
            LOGGER.info("Print appendToBody: {}:{}", key, val);
            body.append(key).append(URLEncoder.encode(val, UTF_8));
        }
    }

上面的代码是从官方给的代码示例里改了一点点。把一些参数提出来,更方便调用。此外加了个返回值,返回官方示例那种的响应结果,示例:

{
    "result": [
        {
            "originTo": "+86155****5678",
            "createTime": "2018-05-25T16:34:34Z",
            "from": "1069********0012",
            "smsMsgId": "d6e3cdd0-522b-4692-8304-a07553cdf591_8539659",
            "status": "000000",
            "countryId": "CN",
            "total": 2
        }
    ],
    "code": "000000",
    "description": "Success"
}

代码改造的来源:
https://support.huaweicloud.com/devg-msgsms/sms_04_0018.html#ZH-CN_TOPIC_0000001606982993__section12610871145
在这里插入图片描述

注意事项

参数

华为云短信的电话号码是需要“+86”的,我改后的代码方法中已经加上了。

华为云短信的变量格式与阿里云不同。
华为云是["value1","value2","value3"]这样一个带中括号的字符串(注意顺序要和模板中的顺序一致
而阿里云是{"key1":"value1","key2":"value2","key3":"value3}这样的json字符串。

华为云中yyyy-MM-dd HH:mm:ss这样的日期格式必须分成两个变量来传递。阿里云的一个就可以。

暂时列出这些,详见官方的变量规范文档。

依赖问题

复制完官方给的代码,你会发现没有依赖。最后我是从这个里面找到了一个jar包。
在这里插入图片描述
在这里插入图片描述
此时可以按官方给的来导入

<dependency> 
  <!--            使用时替换为实际路径-->           
  <systemPath>${project.basedir}/libs/java-sdk-core-XXX.jar</systemPath>            
  <groupId>com.huawei.apigateway</groupId>
  <artifactId>java-sdk-core</artifactId>            
  <version>SDK版本号</version>            
  <scope>system</scope>        
</dependency>

但是后来编译时过不去,只能又本地安装了一下。

maven本地安装

找到自己Maven的路径,按照图示路径放入jar包
在这里插入图片描述
然后在该路径下cmd
执行一段命令

mvn install:install-file -Dfile=java-sdk-core-3.2.5.jar -DgroupId=com.huawei.apigateway -DartifactId=java-sdk-core -Dversion=3.2.5 -Dpackaging=jar

最后把依赖改了就好了

<dependency>   
       <groupId>com.huawei.apigateway</groupId>
       <artifactId>java-sdk-core</artifactId>
       <version>3.2.5</version>
</dependency>

发送短信中其他的问题

如果你复制的不是我改之后的代码,而是官方给的代码,即使按照上面的方法添加了依赖,还是会发现少依赖,少了某个常量值。
我的解决方法:还是从下载的示例里找到那个文件,手动把常量值粘贴过来。

获取模板详情的坑

在这里插入图片描述
这个接口有个坑,官方提示的是传入模板id,我怎么传怎么错。
后来发现其实应该传入的是模板主键id,这里官方提示有误。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值