第一步:注册容联云 https://www.yuntongxun.com/ 注册成功后,可以找到以下信息,新用户注册赠送8块钱,每请求一次发送短信,会扣费。开发者账号中的这些信息在代码中会用到,写代码参考开发者中心中的SDK文档,添加手机号码在“测试号码”模块中添加。
第二步,参考SDK文档写代码
1.根据sdk文档在pom中引入java-sms-sdk依赖,引入gson依赖,建议gson依赖版本用2.8.6,我一开始用的2.8.2版本,结果会报以下错,百度了下,换成2.8.6版本解决
Caused by: java.lang.NoSuchMethodError: com.google.gson.JsonParser.parseString(Ljava/lang/String;)Lcom/google/gson/JsonElement;
2.上述开发者账号中的信息配置在配置文件中,定义配置类读取这些信息,并封装成常量
@Data
@Component
@ConfigurationProperties(prefix = "yuntongxun.sms") // 该注解是取配置文件中读取指定路径下的配置信息,封装成对象,在封装过程中,会用到成员变量的set方法
public class SmsProperties implements InitializingBean { //继承该类,实现该类的afterPropertiesSet方法,该方法就是在配置文件属性被封装完成后才会调用的
/*
account_id:
account_token:
app_id:
server_ip: app.cloopen.com
server_port: 8883
*/
//将配置文件中的配置定义为成员变量,驼峰命名可以自动匹配
private String accountId;
private String accountToken;
private String appId;
private String serverIp;
private String serverPort;
//定义静态变量,将上述参数值赋值给这些静态变量,后续通过类名来获取,赋值的前提是配置文件已经读取完毕并且已经封装到上述成员变量中
public static String ACCOUNT_ID;
public static String ACCOUNT_TOKEN;
public static String APP_ID;
public static String SERVER_IP;
public static String SERVER_PORT;
//该方法就是在配置文件属性被封装完成后才会被调用
@Override
public void afterPropertiesSet() throws Exception {
ACCOUNT_ID = accountId;
ACCOUNT_TOKEN = accountToken;
APP_ID = appId;
SERVER_IP = serverIp;
SERVER_PORT = serverPort;
}
}
3. serviceImpl中的发送短信方法,其中方法需要三个参数。
将账户信息set到sdk对象中
/* mobile ;手机号
* templateId:短信模板,默认为 1
* params:短信模板中需要用到的参数:随机验证码,验证码有效期
*/
public void sendMsg(String mobile, String templateId, String[] params) {
//创建sdk客户端对象
CCPRestSmsSDK sdk = new CCPRestSmsSDK();
//初始化客户端对象
sdk.init(SmsProperties.SERVER_IP, SmsProperties.SERVER_PORT);
//属性赋值
sdk.setAccount(SmsProperties.ACCOUNT_ID, SmsProperties.ACCOUNT_TOKEN);
sdk.setAppId(SmsProperties.APP_ID);
sdk.setBodyType(BodyType.Type_JSON);
String subAppend="1234"; //可选 扩展码,四位数字 0~9999
Object resultCd = null;
Object resultMSg = null;
try {
HashMap<String, Object> result = sdk.sendTemplateSMS(mobile, templateId, params);
resultCd = result.get("statusCode");
if("000000".equals(resultCd)){
//正常返回输出data包体信息(map)
HashMap<String,Object> data = (HashMap<String, Object>) result.get("data");
Set<String> keySet = data.keySet();
for(String key:keySet){
Object object = data.get(key);
System.out.println(key +" = "+object);
}
}else{
//异常返回输出错误码和错误信息
log.info("错误码>>" + resultCd +" 错误信息>> "+ resultMSg);
}
} catch(Exception e) {
if(resultCd != null){
throw new BusinessException((Integer) resultCd, (String)resultMSg, e);
} else {
throw new BusinessException(ResponseEnum.ALIYUN_SMS_ERROR, e);
}
}
}
4. controller层中的方法
@GetMapping("/send/{mobile}")
public ResponseResult send(@PathVariable String mobile){
String msgCode = RandomUtil.fourRandom();
String[] params = {msgCode, "5"};
log.debug("随机验证码为: {}",msgCode);
smsService.sendMsg(mobile,"1", params);
//将验证码存入redis,以便校验客户输入的验证码是否正确且在有效期内,key值为srb:sms:msg:+ mobile
redisTemplate.opsForValue().set("srb:sms:msg:"+ mobile, msgCode, 5, TimeUnit.MINUTES);
return ResponseResult.setResponse(ResponseEnum.SUCCESS).setResponseMsg("短信发送成功");
}
5. 测试结果