当前位置: 首页 > java >正文

java 短信服务

短信

短信服务文明一般都是使用云产品的SDK,例如阿里云中的短信服务
下面是短信服务的文档
短信云服务

依赖引入:

阿里云短信SDK的Maven依赖:

        <dependency><groupId>com.aliyun</groupId><artifactId>dysmsapi20170525</artifactId><version>3.1.0</version></dependency>

nacos中的静态配置文件

在nacos或者yaml文件中编写静态配置文件
下面是nacos中的配置,业务中用@Value获取值
这些在阿里云你获取短信业务的时候提供的

AccessKeyID=
AccessKeySecret=
##阿里短信 配置
sms.aliyun.sign-name=
sms.aliyun.endpoint=
sms.type=
sms.aliyun.template.default.name = 验证码短信
sms.aliyun.template.default.code = 
sms.aliyun.template.default.variable = code
sms.aliyun.template.invite.code = 

accessKeyId 和 accessKeySecret 用于身份认证。

配置项解析

1. sms.aliyun.sign-name

含义:短信签名名称。

作用:
标识短信的发送方,需在阿里云控制台提前申请并通过审核。
接收方看到的短信开头会显示此签名(如:【华天云测】您的验证码是123456)。

注意:

签名需符合阿里云规范(如企业名、应用名、网站名等),不可包含无关内容。

未通过审核的签名会导致短信发送失败。

2. sms.aliyun.endpoint

含义:阿里云短信服务的API接入地址。

作用:
指定请求发送到阿里云的哪个服务器节点,通常使用默认值即可。
若需优化网络延迟,可根据地域选择特定节点(如dysmsapi.ap-southeast-1.aliyuncs.com)。

注意:

默认值适用于大多数场景,无需修改,除非阿里云文档特别说明。

3. sms.type

含义:短信服务商类型标识(通常为项目自定义配置)。

作用:
在多服务商支持的系统中,通过此字段切换短信服务商(例如:1=腾讯云,2=华为云,3=阿里云)。

注意:

此配置为项目自定义逻辑,需结合代码实现判断使用哪个服务商,与阿里云官方SDK无关。

4. sms.aliyun.template.default.name

含义:默认短信模板的名称(项目自定义标识)。

作用:
在代码中通过此名称引用模板,便于管理多个模板(如“验证码短信”“通知短信”等)。
实际发送短信时仍需依赖模板CODE(sms.aliyun.template.default.code)。

注意:

此名称仅用于代码可读性,与阿里云控制台的模板名称无关。

5. sms.aliyun.template.default.code

含义:默认短信模板的CODE。

作用:
指定发送短信时使用的模板(需与阿里云控制台中申请的模板CODE一致)。
例如,验证码短信模板内容可能是:“您的验证码为${code},5分钟内有效。”

注意:

模板需通过阿里云审核,且状态为“审核通过”才能使用。

6. sms.aliyun.template.default.variable

含义:默认短信模板中的变量名。

作用:
替换模板中的动态内容。例如,模板内容为“验证码:${code}”,此处配置变量名为code,发送时需传入code=123456。
代码中需按此变量名构建参数(如Map<String, String> params = Map.of(“code”, “123456”))。

注意:

变量名必须与模板中的占位符完全一致(区分大小写)。

7. sms.aliyun.template.invite.code

含义:邀请类短信模板的CODE。

作用:
区分不同业务场景的短信模板。例如:

default模板用于验证码。

invite模板用于邀请链接(如“您的好友邀请您加入,点击链接:${url}”)。
代码中可根据业务类型选择不同模板发送。

注意:

每个模板需单独申请,且变量名可能不同(如邀请模板的变量名可能是url)。

业务配置文件

一般是两块业务,发送短信验证码,以及邀约

    @Resourceprivate AliSmsConfig aliSmsConfig;@Resourceprivate Client smsClient;
//发送短信验证@Overridepublic void sendVerifySms(SmsVerifyCmd smsVerifyCmd) {SmsVerifyParamDTO param =new SmsVerifyParamDTO(smsVerifyCmd.getCode());checkRedis(smsVerifyCmd.getPhone());sendSms(aliSmsConfig.getSignName(),aliSmsConfig.getVerifyTemplateCode(), smsVerifyCmd.getPhone(),JSON.toJSONString(param));}@Overridepublic void sendInviteSms(SmsInviteRpcCmd inviteRpcCmd) {sendSms(aliSmsConfig.getSignName(),aliSmsConfig.getInviteTemplateCode(), inviteRpcCmd.getPhone(),JSON.toJSONString(inviteRpcCmd.getParam()));}

利用手机号码来做分布式锁检查,后续发送完,例如登录的时候可以从redis中获取验证法还同时拥有了过期时间,一举两得

    /*** 利用手机号码来做分布式锁检查* @param phone*/private void checkRedis(String phone) {boolean lock = redisTemplate.opsForValue().setIfAbsent(CacheEnum.SMS_VERIFY_CODE_REGISTER.getMsg(phone), SMS_REDIS_LOCK_VALUE, SMS_SEND_GAP, TimeUnit.SECONDS);if (!lock) {throw ExFactory.bizException(REDIS_LOCK_ERROR);}}

下面自定义阿里云短信服务的 Client 对象,初始化Client对象的值

@Configuration(enforceUniqueMethods=false)
@Data
public class AliSmsConfig {@Value("${AccessKeyID}")private String accessKeyId;@Value("${AccessKeySecret}")private String accessKeySecret;@Value("${sms.aliyun.endpoint}")private String endPoint;@Value("${sms.aliyun.sign-name}")private String signName;@Value("${sms.aliyun.template.default.code}")private String verifyTemplateCode;@Value("${sms.aliyun.template.invite.code}")private String inviteTemplateCode;@Beanpublic Client aliSmsClient() {Config config = new Config();config.setAccessKeyId(accessKeyId);config.setAccessKeySecret(accessKeySecret);config.setEndpoint(endPoint);try {return new Client(config);} catch (Exception e) {throw new RuntimeException(e);}}}

enforceUniqueMethods=false 这个参数是 Spring 特有的,用于控制配置类中方法名是否要唯一。此参数通常用于避免重复 Bean 定义问题,允许多个方法具有相同的名字。

业务代码

private void sendSms(String signName, String verifyTemplateCode, String phone, String param)  {MsgSmsLog sl =new MsgSmsLog().setId(getLeafId()).setStatus(0).setContent(param).setPhone(phone).setCreateTime(new Date());SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers(phone).setSignName(signName).setTemplateCode(verifyTemplateCode).setTemplateParam(param);SendSmsResponse smsResponse =null;try {smsResponse = smsClient.sendSms(sendSmsRequest);} catch (Exception e) {e.printStackTrace();sl.setStatus(2).setResult(ALIYUN_SMS_SEND_ERROR).setUpdateTime(new Date());smsLogMapper.insert(sl);throw ExFactory.bizException(SMS_SEND_ERROR);}log.info("sms 发送返回信息 :{}",JSON.toJSONString(smsResponse));if(smsResponse!=null &&smsResponse.getStatusCode()==200){if(smsResponse.getBody().getCode().equals(ALIYUN_SMS_SEND_OK)){//发送成功sl.setStatus(1).setResult(ALIYUN_SMS_SEND_OK).setUpdateTime(new Date());smsLogMapper.insert(sl);}else{//发送失败sl.setStatus(2).setResult(smsResponse.getBody().getMessage()).setUpdateTime(new Date());smsLogMapper.insert(sl);throw new BizException(SMS_SEND_ERROR.getKey(),smsResponse.getBody().getMessage());}}else{//请求失败sl.setStatus(2).setResult(ALIYUN_SMS_SEND_ERROR).setUpdateTime(new Date());smsLogMapper.insert(sl);throw new BizException(SMS_SEND_ERROR.getKey(),ALIYUN_SMS_SEND_ERROR);}}

总结

短信推荐方案:
直接调用阿里云、腾讯云等SDK,方便快捷

http://www.xdnf.cn/news/3022.html

相关文章:

  • 域名与DNS理解
  • 4.2.3 MYSQL事务原理分析
  • 纯C协程框架NtyCo
  • 合并两个有序链表
  • xGAP-200-SE7K-L(300T)测试
  • Git 实操:如何使用交互式 Rebase 移除指定提交(真实案例分享)
  • 公路安全知识竞赛主持稿串词
  • Express 文件上传不迷路:req.files 一次性讲明白
  • 洛谷P2142高精度减法题解
  • USB 网卡——RNDIS 控制消息流程
  • AbMole解密生物医学新材料---PCL-PVAc-PEG
  • AUTOSAR图解==>AUTOSAR_RS_InteroperabilityOfAutosarTools
  • 同步与互斥(同步)
  • 【android bluetooth 案例分析 03】【PTS 测试 】【PBAP/PCE/SSM/BV-02-C】
  • 数据中心网络架构:高效规划与自动化设计实践
  • Android 系统发展史
  • php学习笔记(全面且适合新手)
  • Android的Imageview的src属性,如果设置width和height,但是图片本身很小,那么图片会自动缩放到Imageview一样的大小吗
  • GEE进行Theil-Sen Median斜率估计和Mann-Kendall检验
  • RK3568下背光控制 软件与调试技巧
  • 使用 TypeScript 开发并发布一个 npm 包(完整指南)
  • 小刚说C语言刷题——1032分糖果
  • 守护天空安全的科技利剑鼎讯信通(ACNN)的创新实践
  • Flume启动报错
  • MIT6.S081 - Lab11 networking(网络栈)
  • 阿里千问Qwen3技术解析与部署指南 :混合推理架构突破性优势与对DeepSeek R1的全面超越
  • Scrapy框架之CrawlSpider爬虫 实战 详解
  • 23种设计模式-行为型模式之解释器模式(Java版本)
  • Leetcode 3529. Count Cells in Overlapping Horizontal and Vertical Substrings
  • 关于汇编语言与程序设计——子程序设计