确保手机号正确,利用短信网关接口发送验证码,判断验证码一致
步骤:
1、导入HttpClient的依赖:httpclient4.5.5.jar
2、reg页面的js(判断手机号是否为空,手机号的正确性,ajax发送phone的value异步请求,返回json是否符合)
3、controller层编写获取手机号返回json信息
4、在UserServiceImpl中,根据phone调用httpClient网关接口 ***
准备UserServiceImpl中需要的
实体类:返回前端的json类、前端传输过来的实体类
工具类:将数据实体类存入session的工具类、时间常量类、计算时间类、随机验证码类
5、在controller中判断session中的phone并且验证码是否与页面传输的一致,true运行注册
保证手机号的有效性
具体实现:
1、导入HttpClient的依赖
<dependency>
<groupId>org.apache.httpcomponentsgroupId>
<artifactId>httpclientartifactId>
<version>4.5.5version>
dependency>
2、reg页面的js的编写
/* 短信验证码验证 */
$("body").on("click", "#getPhoneCheckCode", function () { //新添加的,也有效
var formId = ‘form_register‘;
var value = $.trim($("#" + formId + " input[name=‘telephone‘]").val());
var errTag = $("#error");
errTag.html("");
var length = value.length;
if (length == 0) {
errTag.html("请输入手机号码");
}else {
var mobile = /^1[3,4,5,6,7,8,9]\d{9}$/;
if (!mobile.test(value)) {
errTag.html("请输入正确的手机号码");
} else {
$("#getPhoneCheckCode").addClass(‘disabled‘);
$("#getPhoneCheckCode").prop(‘disabled‘, true);
$.ajax({
url: "/house/sendCheckCode",
type: "post",
cache: false,
dataType: ‘json‘,
data: { phone: value },
success: function (msg) {
if (msg.status) {
errTag.text(‘验证码已发送到您的手机‘);
var time = 60;
var t = setInterval(function () {
$("#getPhoneCheckCode").text(time + "S后重新获取");
time--;
if (time == 0) {
clearInterval(t);
$("#getPhoneCheckCode").text("获取验证码");
$("#getPhoneCheckCode").prop(‘disabled‘, false);
$("#getPhoneCheckCode").removeClass(‘disabled‘);
}
}, 1000);
} else {
errTag.text(‘未知错误‘);
}
}
});
}
}
});
3、controller层编写获取手机号返回json信息
//发送验证码
@PostMapping("/sendCheckCode")
@ResponseBody
public JSONResult sendCheckCode(String phone) throws Exception{
JSONResult jsonResult = userService.sendCode(phone);
System.out.println(jsonResult.isStatus());
return jsonResult;
}
4、编写业务层前需要做的准备
①json返回数据的对象类(是否成功、显示信息)
public class JSONResult {
private boolean status = true;//表示成功
private String msg;//显示消息
②前端传过来的信息(手机号、验证码,最后一次点击发送验证码的时间)
public class VerifyCodeVo {
/**手机号码*/
private String phone;
/**验证码*/
private String verifyCode;
/**最后一次发送时间*/
private Date lastTime;
③操作session域的工具类,用于将前端传过来的信息保存在session中
public class UserContext {
//定义一个session名称的常量
public static final String VERIFY_CODE_IN_SESSION = "verifyCodeInSession";
//得到httpsession
private static HttpSession getSession() {
//SpringMVC 提供一个RequestContextHolder工具类, 得到Http Servlet API: request,response,session
return ((ServletRequestAttributes)(RequestContextHolder.getRequestAttributes())).getRequest().getSession();
}
//创建一个session对象
public static void setVerifyCode(VerifyCodeVo verifyCodeVo) {
getSession().setAttribute(VERIFY_CODE_IN_SESSION, verifyCodeVo);
}
//获取session对象
public static VerifyCodeVo getCurrentVerifyCode() {
return (VerifyCodeVo) getSession().getAttribute(VERIFY_CODE_IN_SESSION);
}
}
④编写一个常量类,用于存放设置下一次运行发送验证码的时间、验证码有效时间
public class SystemConstant {
/**发送验证码的时间间隔: 单位:秒*/
public static final int BETWEEN_SEND_TIME = 60;
/**验证码的有效时间: 5分钟*/
public static final int VERIFYCODE_VALIDATE_TIME=5*60;
⑤编写一个时间工具类,用于计算当前时间减去上一次点击的时间,判断是否允许发送
public class DateUtils {
public static long betweenTime(Date d1, Date d2) {
return Math.abs((d1.getTime() - d2.getTime())/1000);
}
⑥编写一个随机数工具类,随机生成指定位数验证码
public class RandomUtils {
public static String randomNumber(int length) {
String num = Math.random()+"";
return num.substring(2, length+2);
}
5、在UserServiceImpl中,根据phone参数调用httpClient网关接口
//发送验证码
@Override
public JSONResult sendCode(String phone) throws Exception {
//创建一个JSONResult对象,用于返回数据
JSONResult jsOnResult= new JSONResult();
//获取存在session中的手机短信信息(手机号,验证码,发送时间)
VerifyCodeVo currentVerify = UserContext.getCurrentVerifyCode();
//1.判断时间间隔大于BETWEEN_SEND_TIME. 大于: 表示可以发送
//等于空表示是第一次点击,允许发送
//当前时间减去上一次发送的时间 如果大于,验证码的有效时间,可以发送
if(currentVerify == null ||
DateUtils.betweenTime(new Date(), currentVerify.getLastTime()) > SystemConstant.VERIFYCODE_VALIDATE_TIME){
//发送,使用HttpClient发送, 发送的post
//1.创建客户端
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//2. 准备参数
URI uri = null;
List params = new ArrayList<>();
params.add(new BasicNameValuePair("Uid", "xiao"));//jing2672711802
params.add(new BasicNameValuePair("Key", "d41d8cd98f00b204e980"));
params.add(new BasicNameValuePair("smsMob", phone));
//随机生成的短信验证码,自定义长度为4位
String verifyCode = RandomUtils.randomNumber(4);
params.add(new BasicNameValuePair("smsText", "发给胡老师:验证码"+verifyCode+"【我的小宝贝】"));
uri = new URIBuilder().setScheme("http")
.setHost("utf8.api.smschinese.cn/")
.setParameters(params)
.build();
//3.创建一个HttpPost请求
HttpPost httpPost = new HttpPost(uri);
//4.发送请求
CloseableHttpResponse httpRespOnse= httpClient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
int result = Integer.parseInt(EntityUtils.toString(entity));
if(result<= 0) { //发送失败
throw new RuntimeException("调用短信网关出错了,错误代码:"+result);
}else {
//发送成功,把验证码信息保存到session
VerifyCodeVo verifyCodeVo = new VerifyCodeVo();
verifyCodeVo.setPhone(phone);
verifyCodeVo.setVerifyCode(verifyCode);
verifyCodeVo.setLastTime(new Date());
UserContext.setVerifyCode(verifyCodeVo);
}
if (httpResponse != null) {
httpResponse.close();
}
if (httpClient != null) {
httpClient.close();
}
}else {
//小于, 不能发送
jsonResult.setStatus(false);
}
return jsonResult;
}
使用HttpClient短信网关接口实现手机号验证码注册