Skip to content

场景描述

以官方的注册通知短信为例,用户在官网成功注册后,平台会自动给用户发送一条成功注册通知短信。为了实现这一功能,我们可以集成阿里云短信服务,通过项目发送短信。

注册阿里云并开通短信服务

  1. 注册阿里云账号并完成实名认证。

  1. 进入 阿里云短信服务

点击 立即购买

温馨提示

如果仅是短期内测试联调使用,官方建议优先购买 1000 条短信,以节省成本。

  1. 开通短信服务并创建短信签名和模板。
  • 短信签名:例如 小蚂蚁云

  • 短信模板:例如 尊敬的用户:${name},恭喜您成为官方注册会员,非常感谢您的支持,如需产品咨询或遇紧急情况请及时联系官方QQ客服!

提交审核

根据阿里云短信官方要求,所有 短信签名短信模板 提交后都需要官方审核,审核通过后才可以使用,因此申请时请如何填写。

获取 AccessKey

阿里云控制台 创建 AccessKey(AccessKey ID 和 AccessKey Secret)。

点击 创建 AccessKey

温馨提示

获取 AccessKey IDAccessKey Secret,并妥善保存(注意:AccessKey Secret 只会显示一次)。

添加阿里云 SDK 依赖

pom.xml 中添加阿里云短信 SDK 依赖:

js
<!-- 阿里云SMS短信 -->
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>dysmsapi20170525</artifactId>
</dependency>

xiaomayi-common/xiaomayi-sms 模块中已经引入此依赖,在实际使用时直接引入以下依赖即可:

js
<!-- 短信依赖模块 -->
<dependency>
    <groupId>com.xiaomayi</groupId>
    <artifactId>xiaomayi-sms</artifactId>
</dependency>

配置阿里云短信服务

application-aliyun.yml 中配置阿里云短信服务的参数:

js
# 阿里云
aliyun:
  # 短信配置
  sms:
    accessKeyId: 账号ID
    accessKeySecret: 账号秘钥
    regionId: cn-hangzhou
    signName: 短信签名
    templateCode: 短信模板
    endpoint: dysmsapi.aliyuncs.com

短信 YML 文件配置解析文件:

js
package com.xiaomayi.sms.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * <p>
 * 阿里云SMS短信配置类
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-05-31
 */
@Configuration
@ConfigurationProperties(prefix = "aliyun.sms")
public class AliyunSmsConfig {

    /**
     * 服务ID
     */
    private static String accessKeyId;

    /**
     * 服务秘钥
     */
    private static String accessKeySecret;

    /**
     * 区域ID
     */
    private static String regionId;

    /**
     * 服务节点
     */
    private static String endpoint;

    /**
     * 短信签名
     */
    private static String signName;

    /**
     * 短信模板编号
     */
    private static String templateCode;

    public static String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        AliyunSmsConfig.accessKeyId = accessKeyId;
    }

    public static String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        AliyunSmsConfig.accessKeySecret = accessKeySecret;
    }

    public static String getRegionId() {
        return regionId;
    }

    public void setRegionId(String regionId) {
        AliyunSmsConfig.regionId = regionId;
    }

    public static String getEndpoint() {
        return endpoint;
    }

    public void setEndpoint(String endpoint) {
        AliyunSmsConfig.endpoint = endpoint;
    }

    public static String getSignName() {
        return signName;
    }

    public void setSignName(String signName) {
        AliyunSmsConfig.signName = signName;
    }

    public static String getTemplateCode() {
        return templateCode;
    }

    public void setTemplateCode(String templateCode) {
        AliyunSmsConfig.templateCode = templateCode;
    }
}

创建短信服务工具类

xiaomayi-common/xiaomayi-sms 短信模块中,创建一个工具类 AliyunSmsUtil,用于发送短信:

js
package com.xiaomayi.sms.utils;

import com.alibaba.fastjson2.JSON;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.sms.config.AliyunSmsConfig;
import com.xiaomayi.sms.dto.SmsSendDTO;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 阿里云SMS短信工具类
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-05-31
 */
@Slf4j
public class AliyunSmsUtil {

    /**
     * 创建客户端连接
     *
     * @return 返回结果
     * @throws Exception 异常处理
     */
    public static Client createClient() throws Exception {
        Config config = new Config()
                // 阿里云短信AccessKeyId
                .setAccessKeyId(AliyunSmsConfig.getAccessKeyId())
                // 阿里云短信AccessKeySecret
                .setAccessKeySecret(AliyunSmsConfig.getAccessKeySecret());
        config.endpoint = AliyunSmsConfig.getEndpoint();
        // 返回结果
        return new Client(config);
    }

    /**
     * 发哦上短信
     *
     * @param smsSendDTO 参数
     * @return 返回结果
     */
    public static R sendSms(SmsSendDTO smsSendDTO) {
        // 手机号
        String mobile = smsSendDTO.getMobile();
        // 参数
        String params = JSON.toJSONString(smsSendDTO);
        // 发送短信
        return sendSms(mobile, AliyunSmsConfig.getTemplateCode(), params);
    }


    /**
     * 发送短信
     *
     * @param mobile 手机号码
     * @param params 短信模板
     * @return JSON格式参数
     */
    public static R sendSms(String mobile, String params) {
        return sendSms(mobile, AliyunSmsConfig.getTemplateCode(), params);
    }

    /**
     * 发送短信
     *
     * @param mobile       手机号码
     * @param templateCode 短信模板
     * @param params       JSON格式参数
     */
    public static R sendSms(String mobile, String templateCode, String params) {
        // 短信发送结果
        String message = "";
        try {
            // 创建一个短信服务客户端实例,使用预设的KEYID和SECRET进行身份认证
            Client client = createClient();
            // 创建SendSmsRequest对象,设置发送短信所需参数
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    // 设置接收短信的手机号码
                    .setPhoneNumbers(mobile)
                    // 设置模板参数,根据实际业务场景替换为动态内容
                    .setTemplateParam(params)
                    // 设置短信模板CODE
                    .setTemplateCode(templateCode)
                    // 设置短信签名名称
                    .setSignName(AliyunSmsConfig.getSignName());
            // 调用客户端的sendSmsWithOptions方法发送短信,并传入RuntimeOptions以配置额外的运行时选项
            // 这段代码执行后会发送短信验证码到指定的手机号码上,但此处为了简洁没有打印API返回的结果
            client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());

            SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
            SendSmsResponseBody body = sendSmsResponse.getBody();
            if ("ok".equalsIgnoreCase(body.getCode())) {
                // 返回结果
                return R.ok(null, body.getMessage());
            }
            // 返回结果
            return R.failed(body.getMessage());
        } catch (Exception e) {
            message = e.getMessage();
            log.error("短信发送失败:{}", message);
        }
        // 返回结果
        return R.failed(message);
    }

}

测试短信发送

编写一个简单的测试类,验证短信发送功能:

js
package com.xiaomayi.admin.controller.demo;

import com.alibaba.fastjson2.JSON;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.ratelimiter.annotation.RateLimiter;
import com.xiaomayi.sms.annotation.SmsLog;
import com.xiaomayi.sms.dto.SmsSendDTO;
import com.xiaomayi.sms.enums.SmsType;
import com.xiaomayi.system.service.EmailTemplateService;
import com.xiaomayi.system.service.SmsTemplateService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 案例测试 前端控制器
 * </p>
 *
 * @author 小蚂蚁云团队
 * @since 2024-05-26
 */
@Slf4j
@RestController
@RequestMapping("/example")
@AllArgsConstructor
public class ExampleController {

    private final SmsTemplateService smsTemplateService;

    /**
     * 短信发送测试
     *
     * @param smsSendDTO 参数
     * @return 返回结果
     */
    @SmsLog(title = "登录短信", type = SmsType.LOGIN)
    @PostMapping("/sendSms")
    public R sendSms(@RequestBody @Validated SmsSendDTO smsSendDTO) {
        // 接收者ID
        smsSendDTO.setReceiveId(1);
        // 接收人类型:1-系统用户 2-会员用户 3-其他
        smsSendDTO.setReceiveType(2);
        // 业务类型:1-订单 2-其他
        smsSendDTO.setBizType(1);
        // 业务ID
        smsSendDTO.setBizId(1);
        // 业务内容
        Map<String, Object> bizMap = new HashMap<>();
        bizMap.put("orderId", 1);
        bizMap.put("orderNo", "20240614000001");
        smsSendDTO.setBizContent(JSON.toJSONString(bizMap));

        // 模板参数
        Map<String, Object> map = new HashMap<>();
        map.put("code", "123456");
        smsSendDTO.setParams(map);

        // 发送短信
        return smsTemplateService.sendSms(smsSendDTO);
    }
}

用户收到短信

【小蚂蚁云】尊敬的用户:xiaomayicloud@163.com,恭喜您成为官方注册会员,非常感谢您的支持,如需产品咨询或遇紧急情况请及时联系官方QQ客服!

总结

通过以上步骤,我们成功在项目中集成了阿里云短信服务,实现了订单创建后的短信通知功能,集成阿里云短信服务的好处包括:

高效可靠:阿里云短信服务具有高并发、高可靠性的特点,适合电商平台等需要大量发送短信的场景。
灵活配置:支持自定义短信模板和签名,满足不同业务需求。
易于集成:通过阿里云 SDK,可以快速集成短信服务,减少开发工作量。
成本可控:按需付费,成本透明,适合中小型企业。

小蚂蚁云团队 · 提供技术支持

小蚂蚁云 新品首发
新品首发,限时特惠,抢购从速! 全场95折
赋能开发者,助理企业发展,提供全方位数据中台解决方案。
获取官方授权