总览:
在common模块下引入短信验证码的依赖项(生成4位随机数):
在web模块下的resources/application.yml,添加配置信息(京东万象):
#短信配置
jdwx:
sms:
url: https://way.jd.com/chuangxin/dxjk
appkey: 3680fa919b771148da626bbcbd459475
content: 【大富科技】你的验证码是:%s,3分钟内有效,请勿泄露给他人
login-text: 【大富科技】登录验证码是:%s,3分钟内有效,请勿泄露给他人
realname:
url: https://way.jd.com/youhuoBeijing/test
appkey: 3680fa919b771148da626bbcbd459475
在web模块下的config包,创建一个短信配置类(JdwxSmsConfig):
package com.bjpowernode.front.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "jdwx.sms")
public class JdwxSmsConfig {
private String url;
private String appkey;
private String content;
private String loginText;
public String getLoginText() {
return loginText;
}
public void setLoginText(String loginText) {
this.loginText = loginText;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAppkey() {
return appkey;
}
public void setAppkey(String appkey) {
this.appkey = appkey;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
在web模块下的service包,创建一个短信接口(SmsService):
package com.bjpowernode.front.service;
public interface SmsService {
/**
* @param phone 手机号
* @return true:发送成功,false 其他情况
*/
boolean sendSms(String phone);
}
并实现这个接口(SmsCodeRegisterImpl):注册发送短信验证码
步骤:
1、随机生成4位短信验证码
2、使用http接受用户响应的json数据(包括电话、页面状态数等)
3、使用fastjson解析json数据,验证一下json数据(电话是否满足格式要求、页面状态是否正常等)
4、把验证码暂时存储到redis中(注入redis模板,在common模块中的RedisKey中写入相应的KEY)
package com.bjpowernode.front.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.bjpowernode.common.constants.RedisKey;
import com.bjpowernode.front.config.JdwxSmsConfig;
import com.bjpowernode.front.service.SmsService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* 注册发送短信验证码
*/
@Service(value = "smsCodeRegisterImpl")
public class SmsCodeRegisterImpl implements SmsService {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private JdwxSmsConfig smsConfig;
@Override
public boolean sendSms(String phone) {
boolean send = false;
// 设置短信内容
String random = RandomStringUtils.randomNumeric(4);
System.out.println("注册验证码的随机数 random="+random);
//更新content中的 %s 【大富科技】你的验证码是:%s,3分钟内有效,请勿泄露给他人
String content = String.format(smsConfig.getContent(), random);
//使用HttpClient发送 get 请求给第三方。
CloseableHttpClient client = HttpClients.createDefault();
//https://way.jd.com/chuangxin/dxjk?mobile=13568813957&content=
//【创信】你的验证码是:5873,3分钟内有效!&appkey=您申请的APPKEY
String url = smsConfig.getUrl()+"?mobile="+phone
+"&content=" + content
+"&appkey="+smsConfig.getAppkey();
HttpGet get = new HttpGet(url);
try{
CloseableHttpResponse response = client.execute(get);
if( response.getStatusLine().getStatusCode() == HttpStatus.SC_OK ){ // 状态码:200
//得到返回的数据,json
//String text = EntityUtils.toString(response.getEntity());
String text="{\n" +
" \"code\": \"10000\",\n" +
" \"charge\": false,\n" +
" \"remain\": 1305,\n" +
" \"msg\": \"查询成功\",\n" +
" \"result\": {\n" +
" \"ReturnStatus\": \"Success\",\n" +
" \"Message\": \"ok\",\n" +
" \"RemainPoint\": 420842,\n" +
" \"TaskID\": 18424321,\n" +
" \"SuccessCounts\": 1\n" +
" }\n" +
"}";
//解析json
if(StringUtils.isNotBlank(text)){ //
// fastjson
JSONObject jsonObject = JSONObject.parseObject(text);
if("10000".equals(jsonObject.getString("code"))){ //第三方接口调用成功
//读取result中的key:ReturnStatus
if("Success".equalsIgnoreCase(
jsonObject.getJSONObject("result").getString("ReturnStatus"))){
//短信发送成功
send = true;
//把短信验证码,存到redis
String key = RedisKey.KEY_SMS_CODE_REG + phone;
stringRedisTemplate.boundValueOps(key).set(random,3 , TimeUnit.MINUTES);
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return send;
}
}
上面用到httpclient类,在common模块下引入依赖:
上面用到fastjson解析json,在common模块下引入依赖:
验证码存入redis时更新添加相应的RedisKey(在common模块constants包下的RedisKey类):
/*注册时,短信验证码 SMS:REG:手机号*/
public static final String KEY_SMS_CODE_REG = "SMS:REG:";
在web模块下创建对应的controller类:
package com.bjpowernode.front.controller;
import com.bjpowernode.common.constants.RedisKey;
import com.bjpowernode.common.enums.RCode;
import com.bjpowernode.common.util.CommonUtil;
import com.bjpowernode.front.service.SmsService;
import com.bjpowernode.front.view.RespResult;
import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Api(tags = "短信业务")
@RestController
@RequestMapping("/v1/sms")
public class SmsController extends BaseController {
@Resource(name = "smsCodeRegisterImpl")
private SmsService smsService;
@Resource(name = "smsCodeLoginImpl")
private SmsService loginSmsService;
/**发送注册验证码短信*/
@GetMapping("/code/register")
public RespResult sendCodeRegister(@RequestParam String phone){
RespResult result = RespResult.fail();
if(CommonUtil.checkPhone(phone)){
//判断redis中是否有这个手机号的验证码
String key = RedisKey.KEY_SMS_CODE_REG + phone;
if(stringRedisTemplate.hasKey(key)){ // 判断验证码key是否出现过在redis中,就是在3分钟之内发送过一次,这个验证码还可以使用
result = RespResult.ok();
result.setRCode(RCode.SMS_CODE_CAN_USE);
} else {
boolean isSuccess = smsService.sendSms(phone);
if( isSuccess ){
result = RespResult.ok();
}
}
} else {
result.setRCode(RCode.PHONE_FORMAT_ERR);
}
return result;
}
/**发送登录验证码短信*/
@GetMapping("/code/login")
public RespResult sendCodeLogin(@RequestParam String phone){
RespResult result = RespResult.fail();
if(CommonUtil.checkPhone(phone)){
//判断redis中是否有这个手机号的验证码
String key = RedisKey.KEY_SMS_CODE_LOGIN + phone;
if(stringRedisTemplate.hasKey(key)){
result = RespResult.ok();
result.setRCode(RCode.SMS_CODE_CAN_USE);
} else {
boolean isSuccess = loginSmsService.sendSms(phone);
if( isSuccess ){
result = RespResult.ok();
}
}
} else {
result.setRCode(RCode.PHONE_FORMAT_ERR);
}
return result;
}
}