使用HttpClient短信网关接口实现手机号验证码注册

Posted 64byte

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用HttpClient短信网关接口实现手机号验证码注册相关的知识,希望对你有一定的参考价值。

技术图片

确保手机号正确,利用短信网关接口发送验证码,判断验证码一致

步骤:

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的依赖

<!-- httpclient短信网关 -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.5</version>
</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<NameValuePair> 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短信网关接口实现手机号验证码注册的主要内容,如果未能解决你的问题,请参考以下文章

js实现输入手机验证码后点击提交按钮验证手机输入的验证码和发送的验证码是不是一致

php 调用短信 短信宝 手机号验证码登录简单实现

自动填充短信验证码(使用ContentObserver)

06-手机登录&token生成&容联云短信验证&用户认证和网关整合(网关做统一权限认证)

Web项目中手机注册短信验证码实现的全流程及代码

106短信简单描述与验证码短信接口介绍