使用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;
}

 

posted @ 2020-07-02 20:52  64Byte  阅读(455)  评论(0编辑  收藏  举报