总览:
在common模块下引入短信验证码的依赖项(生成4位随机数):
在web模块下的resources/application.yml,添加配置信息(京东万象):
#短信配置
jdwx:sms:url: https://way.jd.com/chuangxin/dxjkappkey: 3680fa919b771148da626bbcbd459475content: 【大富科技】你的验证码是:%s,3分钟内有效,请勿泄露给他人login-text: 【大富科技】登录验证码是:%s,3分钟内有效,请勿泄露给他人realname:url: https://way.jd.com/youhuoBeijing/testappkey: 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 {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Resourceprivate JdwxSmsConfig smsConfig;@Overridepublic 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=您申请的APPKEYString 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" +"}";//解析jsonif(StringUtils.isNotBlank(text)){ // // fastjsonJSONObject jsonObject = JSONObject.parseObject(text);if("10000".equals(jsonObject.getString("code"))){ //第三方接口调用成功//读取result中的key:ReturnStatusif("Success".equalsIgnoreCase(jsonObject.getJSONObject("result").getString("ReturnStatus"))){//短信发送成功send = true;//把短信验证码,存到redisString 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;}
}