参考文档
短信服务首页:https://help.aliyun.com/product/44282.html?spm=a2c4g.11174283.6.540.76d22c429dLh6Q
阿里云短信服务文档使用指引:https://help.aliyun.com/document_detail/59210.html?spm=a2c4g.11174283.4.1.76d22c429dLh6Q
安装Java SDK:https://help.aliyun.com/document_detail/112148.html?spm=a2c4g.11186623.6.646.73df50a4ldAjRC
API自动生成:https://api.aliyun.com/?spm=a2c4g.11186623.2.17.5dac60e2EGbsmB#/?product=Dysmsapi&lang=JAVA
使用指南
使用“阿里云短信服务文档使用指引”文档做好准备工作后,再使用“API自动生成”生成相应的API就可用使用了。
对于频繁使用的测试手机号码,可用设置白名单:https://dysms.console.aliyun.com/dysms.htm?spm=5176.12818093.recent.ddysms.488716d0UWJE0c#/system/setting/safe
短信发送(SendSms)开发代码
使用此代码的时候,直接复制WxLoginSendMessageImpl(微信登录的短信验证码)类,然后修改信息即可。
请求信息类,用来请求短信发送(SendSms)接口的返回json。
import lombok.Builder; import lombok.Data; import java.io.Serializable; /** * 短信验证码的code * * @author shuaige.zheng */ @Builder @Data public class SmsTemplateParam implements Serializable { private static final long serialVersionUID = 7693125133210884584L; /** * 验证码code */ private String code; }
返回信息类,用来接收请求短信发送(SendSms)接口的返回json。
import lombok.Data; @Data public class SmsDataModel { /** * 状态码的描述 */ private String message; /** * 请求状态码 */ private String code; /** * 发送id */ private String requestId; /** * 发送回执ID,可根据该ID在接口QuerySendDetails中查询具体的发送状态。 */ private String bizId; }
保存日志的po
import lombok.Data; import tk.mybatis.mapper.annotation.KeySql; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable; import java.time.LocalDateTime; /** * @author shuaige */ @Data @Table(name = "push_short_message_log") public class PushShortMessageLogDO implements Serializable { private static final long serialVersionUID = -70489226920770339L; /** * 主键 */ @Id @Column(name = "`id`") @KeySql(useGeneratedKeys = true) private Long id; /** * 1 发送微信小程序登录码 */ private Integer sendType; /** * 用户id */ private Long userId; /** * 状态码的描述 */ private String message; /** * 发送id */ private String requestId; /** * 发送回执id,可根据该id在接口querysenddetails中查询具体的发送状态。 */ private String bizId; /** * 请求状态码 */ private String code; /** * 创建时间 */ private LocalDateTime createTime; }
日志mapper
import com.anchi.car.coresystem.consumer.dao.entity.PushShortMessageLogDO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Component; import java.util.Map; @Component @Mapper public interface PushShortMessageLogMapper extends tk.mybatis.mapper.common.Mapper<PushShortMessageLogDO> { }
请求方法
/** * 发送短信 * * @param phoneNumbers 接收短信的手机号码。 * 格式: * <p> * 国内短信:11位手机号码,例如15951955195。 * 国际/港澳台消息:国际区号+号码,例如85200000000。 * 支持对多个手机号码发送短信,手机号码之间以英文逗号(,)分隔。上限为1000个手机号码。批量调用相对于单条调用及时性稍有延迟。 * @param signName 短信签名名称。 * @param templateCode 短信模板ID。 * @param templateParam 短信模板变量对应的实际值,JSON格式 * @return */ public SmsDataModel sendSms(String phoneNumbers, String signName, String templateCode, String templateParam) { DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAI21dsfiHfTI", "zoasdFsdfsdsdfsgpfUQzQjbx2"); IAcsClient client = new DefaultAcsClient(profile); CommonRequest request = new CommonRequest(); request.setMethod(MethodType.POST); request.setDomain("dysmsapi.aliyuncs.com"); request.setVersion("2017-05-25"); // 调用SendSms发送短信。 request.setAction("SendSms"); request.putQueryParameter("RegionId", "cn-hangzhou"); request.putQueryParameter("PhoneNumbers", phoneNumbers); request.putQueryParameter("SignName", signName); request.putQueryParameter("TemplateCode", templateCode); request.putQueryParameter("TemplateParam", templateParam); try { CommonResponse response = client.getCommonResponse(request); String data = response.getData(); if (StringUtils.isNotBlank(data)) { SmsDataModel smsDataModel = JSON.parseObject(data, SmsDataModel.class); if (smsDataModel != null && "OK".equalsIgnoreCase(smsDataModel.getCode())) { logger.info("send success"); return smsDataModel; } } } catch (ClientException e) { logger.error("sms response error", e); } return null; }
构建发送短信的模板基础类
import com.anchi.car.coresystem.consumer.dao.entity.PushShortMessageLogDO; import com.anchi.car.coresystem.consumer.dao.mapper.PushShortMessageLogMapper; import com.anchi.car.coresystem.consumer.service.shortmessage.aliyun.SmsDataModel; import com.anchi.car.coresystem.consumer.service.shortmessage.aliyun.SmsFactory; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service @Data public abstract class AbstractSendMessage<T> { @Autowired private SmsFactory smsFactory; @Resource private PushShortMessageLogMapper pushShortMessageLogMapper; /** * 中文签名 */ protected static final String ZH_CN_SIGN_NAME = "常州安驰汽车租赁有限公司"; /** * 英文签名 */ protected static final String EN_SIGN_NAME = "AmyExpress"; /** * 获取模板参数 */ abstract String getTemplateParam(T templateParam); /** * 获取模板编号 */ abstract String getTemplateCode(); /** * 获取模板签名 * * @param isabroad 是否国外 */ private String getSignName(boolean isabroad) { if (isabroad) { return EN_SIGN_NAME; } else { return ZH_CN_SIGN_NAME; } } /** * 模板 * * @param phones 接收短信的手机号码。 * 格式: * <p> * 国内短信:11位手机号码,例如15951955195。 * 国际/港澳台消息:国际区号+号码,例如85200000000。 * 支持对多个手机号码发送短信,手机号码之间以英文逗号(,)分隔。上限为1000个手机号码。批量调用相对于单条调用及时性稍有延迟。 * @param isabroad 是否国外 * @param templateParam 短信模板变量对应的实际值,JSON格式 * @param sendType 1 登录 2 注册 */ public boolean sendMessage(String phones, boolean isabroad, T templateParam, int sendType, long userId) { // 发送短信 SmsDataModel smsDataModel = smsFactory.sendSms(phones, getSignName(isabroad), getTemplateCode(), getTemplateParam(templateParam)); if (smsDataModel != null) { // 记录发送记录 PushShortMessageLogDO messageLog = new PushShortMessageLogDO(); messageLog.setSendType(sendType); messageLog.setUserId(userId); messageLog.setMessage(smsDataModel.getMessage()); messageLog.setRequestId(smsDataModel.getRequestId()); messageLog.setBizId(smsDataModel.getBizId()); messageLog.setCode(smsDataModel.getCode()); pushShortMessageLogMapper.insertSelective(messageLog); return true; } return false; } }
微信登录的短信验证码
import com.alibaba.fastjson.JSON; import org.springframework.stereotype.Service; /** * 微信登录的短信模板 * * @author shaoshuai.zheng */ @Service public class WxLoginSendMessageImpl extends AbstractSendMessage<String> { @Override String getTemplateParam(String code) { // 构建参数 SmsTemplateParam build = SmsTemplateParam .builder() .code(code) .build(); // 返回 return JSON.toJSONString(build); } @Override String getTemplateCode() { return "SMS_153915225"; } }
发送代码
// 发送验证码 boolean sendMessage = wxLoginSendMessage.sendMessage("13212345678,12012345678", false, "1234",1, 120);