短信验证码实现

Posted Dota_小川

tags:

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

项目做了登录改密功能需要验证码的功能.

思路:页面点击获取验证码按钮,发送请求到后台,携带用户名作为参数.后台做一个servlet查询该用户的手机号.生成随机验证码.将验证码(+消息)+tel作为参数+其他接口参数拼成url调用第三方服务(云信).

实现:

1.页面js方法

 function get_code_time(){
     var uname = $("#uname").val();
     if(!uname){ 
         $("#users").html("请先输入您的用户名!");//提示信息
     }else{
         var data="uname="+uname;
         $.get("sendCodes",{uname:uname},function(data){
             code_time();//记时方法
        //根据servlet返回的json判断短信发送状态
if(data=="0"){ alert("短信验证码发送失败,请重新获取"); }else if(data=="1"){ alert("用户名未注册"); }else if(data=="2"){ alert("用户名无效或手机号未注册"); }else if(data=="3"){ alert("短信发送成功"); }else if(data=="4"){ alert("验证码超时"); } }); } }
var wait = 60;
 function code_time(){
    // alert(567);
     if(wait==0){
         $("#codes").removeAttr("disabled");//移除获取验证码按钮的disabled属性
         $("#codes").val("重新获取验证码");
        $("#msgs").val("");
         wait =60;
     }else{
         $("#codes").attr("disabled", true);//设置获取验证码按钮为不可触发
         $("#codes").val("(" + wait + ")秒后获取验证码");
         wait--;
         setTimeout("code_time()", 1000);
     }
 }

2.后台servlet:servlet的路径是上面js方法中的sendCodes

public class SendCodes extends HttpServlet {


    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {


        String ret="",uname="",tel = "";
            uname=request.getParameter("uname");
            //判断用户名是否为空
            if(uname==null || "".equals(uname)){
                response.getWriter().write("1");
                return;
            }

            //通过用户名找到电话号码
            String sql = "select ccu.tel from table_user tu where tu.user_name= ? ";
            Session session = new Session(EcConnection.get());//自己封装的获取数据库连接的方法
            try{
                tel = session.queryForColumn(String.class, sql, uname);
            }catch (Exception e) {
                e.printStackTrace();
            }finally{
                session.close();
            }//手机号为空2
        if (tel==null || "".equals(tel)) {
            response.getWriter().write("2");
            return;
        }
        //生成验证码
        int Random  = (int) ((Math.random()*9+1)*100000);//随机生成的6位数(验证码)

        //发送到手机
        //SMSTest sms=new SMSTest();
        String mes= "您的验证码:"+String.valueOf(Random)+",有效时间5分钟" ;
        String msg = "";
        try {
      //由于服务器不能解析调用发送短信接口拼接的url,
      //发送短信,调另一服务,其实就是一个servlet,访问返回的是调用短信接口的发送状态码, Map<String, String> paraMap = new HashMap<String, String>(); paraMap.put("mes", mes); msg = HttpClient.post("http://127.0.0.1:8082/SendSms/semdsms?tel="+tel, paraMap);//自己封装的httpClientpost方法,下面粘代码 System.out.println(msg); //如果返回的是错误服务错误信息 if("发送短信错误".equals(msg)){ response.getWriter().write("0"); return; } }catch (Exception e) { e.printStackTrace(); response.getWriter().write("0"); return; } //新建一个实体类对象,把它做为一个容器来放验证码,帐号和收取验证码时间。服务不关闭,或是30分钟后就登陆无效 SmsMessageBean b = new SmsMessageBean(uname,Random+"",System.currentTimeMillis()); EcContainer.RandomMap.put(uname, b); response.getWriter().write("3"); }

HttpClient访问的http://127.0.0.1:8082/SendSms/semdsms的servlet:service方法

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String tel = req.getParameter("tel");
        String mes = req.getParameter("mes");
        
        SMSTest sms = new SMSTest();
        PrintWriter pw = resp.getWriter();
        try {
            String msg = sms.send(mes, tel);
            pw.write(msg);
        } catch (Exception e) {
            e.printStackTrace();
            pw.write("发送短信错误");
        }
    }

第三方短息接口:

public class SMS{

    private static final String addr = "http://api.sms.cn/mt/";
    //接口服务注册的用户id
    private static final String userId = "*****";
    
    /*
     * 如uid是:test,登录密码是:123123 
       pwd=md5(123123test),即
       pwd=b9887c5ebb23ebb294acab183ecf0769
       
           线生成地址:http://www.sms.cn/password
     */
//接口注册的密码:经过拼接字符串和md5加密后的结果
   private static final String pwd = "-----------------"; private static final String encode = "utf8"; //编码 public String send(String msgContent, String mobile) throws Exception { //组建请求 String straddr = addr + "?uid="+userId+ "&pwd="+pwd+ "&mobile="+mobile+ //手机号 "&encode="+encode+ "&content=" +URLEncoder.encode(msgContent, "UTF-8"); //编码格式要对应上,不然就收不到短信 StringBuffer sb = new StringBuffer(straddr);//发送请求 URL url = new URL(sb.toString()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); BufferedReader in = new BufferedReader(new InputStreamReader( url.openStream())); //返回结果 String inputline = in.readLine(); String msg=inputline.substring(9, 12); System.out.println("smstest="+msg); return msg; } }

自己封装的httpClient方法: 直接使用即可.

public static String post(String baseUrl, Map<String, String> paramsMap) {
        StringBuilder doc = new StringBuilder();
        try {
            StringBuilder queryString = new StringBuilder();
            for (Iterator<String> it = paramsMap.keySet().iterator(); it
                    .hasNext();) {
                String paramName = it.next().toString();
                Object paramValue = paramsMap.get(paramName);
                if (paramValue == null) {
                    paramValue = "";
                }
                queryString
                        .append(paramName)
                        .append("=")
                        .append(URLEncoder.encode(paramValue.toString(), encode))
                        .append("&");
            }
            if (queryString.length() > 0) {
                queryString.deleteCharAt(queryString.length() - 1);
            }
            URL url = new URL(baseUrl);
            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
            uc.setRequestMethod("POST");
            // 设置参数--begin
            uc.setDoOutput(true);
            byte[] b = queryString.toString().getBytes();
            uc.getOutputStream().write(b, 0, b.length);
            uc.getOutputStream().flush();
            uc.getOutputStream().close();
            // 参数设置--end
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    uc.getInputStream(), encode));
            String line = null;
            while ((line = in.readLine()) != null) {
                // 处理特殊字符
                line = line.replace("&amp;", "&");
                doc.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return doc.toString();
    }

 

以上是关于短信验证码实现的主要内容,如果未能解决你的问题,请参考以下文章

借助云开发实现小程序短信验证码的发送

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

SpringBoot 实现手机发送短信验证码

使用 SSM 框架实现发送手机短信验证码

各大APP注册时发送短信验证码是怎么实现的?

iOS 短信验证码倒计时按钮的实现