java + servlet+ jsp实现发送手机短信验证码
【1】选择平台,完成认证。
短信登陆平台很多,自己可以看个人爱好选择。
我们使用的API平台是:秒嘀云: https://sms.miaodiyun.com/login.html
注册该平台,完成认证就可以获取到参数:ACCOUNT SID , AUTH TOKEN , API
【2】创建短信模板 (该模板必须创建,通过平台审核只会才可以使用,而且后续的参数 smsContent 要和模板中的一致 )
【3】发送短信接口
http://www.miaodiyun.com/doc/https_sms.html
编写java手机短信发送代码
【4】项目目录结构 (idea 中创建的普通web工程)
【5】Config.java
1 public class Config { 2 /** 3 * url前半部分 4 */ 5 public static final String BASE_URL = " https://openapi.miaodiyun.com/distr*******dSMS"; 6 7 /** 8 * 开发者注册后系统自动生成的账号,可在官网登录后查看 9 */ 10 public static final String ACCOUNT_SID = "fcf340ac***********915927"; 11 12 /** 13 * 开发者注册后系统自动生成的TOKEN,可在官网登录后查看 14 */ 15 public static final String AUTH_TOKEN = "648384a1***********2c33e4f"; 16 17 /** 18 * 响应数据类型, JSON或XML 19 */ 20 public static final String RESP_DATA_TYPE = "JSON"; 21 }
【6】http请求工具
1 package com.miaodi.comment; 2 3 4 5 import org.apache.commons.codec.digest.DigestUtils; 6 7 import java.io.BufferedReader; 8 import java.io.IOException; 9 import java.io.InputStreamReader; 10 import java.io.OutputStreamWriter; 11 import java.net.URL; 12 import java.net.URLConnection; 13 14 /** 15 * http请求工具 16 */ 17 public class HttpUtil { 18 /** 19 * 构造通用参数timestamp、sig和respDataType 20 * 21 * @return 22 */ 23 public static String createCommonParam(String sid,String token) { 24 // 时间戳 25 long timestamp = System.currentTimeMillis(); 26 // 签名 27 String sig = DigestUtils.md5Hex(sid + token + timestamp); 28 return "×tamp=" + timestamp + "&sig=" + sig + "&respDataType=" + Config.RESP_DATA_TYPE; 29 } 30 31 /** 32 * post请求 33 * 34 * @param url 35 * 功能和操作 36 * @param body 37 * 要post的数据 38 * @return 39 * @throws IOException 40 */ 41 public static String post(String url, String body) { 42 System.out.println("body:" + System.lineSeparator() + body); 43 44 String result = ""; 45 try { 46 OutputStreamWriter out = null; 47 BufferedReader in = null; 48 URL realUrl = new URL(url); 49 URLConnection conn = realUrl.openConnection(); 50 51 // 设置连接参数 52 conn.setDoOutput(true); 53 conn.setDoInput(true); 54 conn.setConnectTimeout(5000); 55 conn.setReadTimeout(20000); 56 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 57 // 提交数据 58 out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); 59 out.write(body); 60 out.flush(); 61 62 // 读取返回数据 63 in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); 64 String line = ""; 65 boolean firstLine = true; // 读第一行不加换行符 66 while ((line = in.readLine()) != null) { 67 if (firstLine) { 68 firstLine = false; 69 } else { 70 result += System.lineSeparator(); 71 } 72 result += line; 73 } 74 75 } catch (Exception e) { 76 e.printStackTrace(); 77 } 78 return result; 79 } 80 81 /** 82 * 回调测试工具方法 83 * 84 * @param url 85 * @return 86 */ 87 public static String postHuiDiao(String url, String body) { 88 String result = ""; 89 try { 90 OutputStreamWriter out = null; 91 BufferedReader in = null; 92 URL realUrl = new URL(url); 93 URLConnection conn = realUrl.openConnection(); 94 95 // 设置连接参数 96 conn.setDoOutput(true); 97 conn.setDoInput(true); 98 conn.setConnectTimeout(5000); 99 conn.setReadTimeout(20000); 100 101 // 提交数据 102 out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); 103 out.write(body); 104 out.flush(); 105 106 // 读取返回数据 107 in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); 108 String line = ""; 109 boolean firstLine = true; // 读第一行不加换行符 110 while ((line = in.readLine()) != null) { 111 if (firstLine) { 112 firstLine = false; 113 } else { 114 result += System.lineSeparator(); 115 } 116 result += line; 117 } 118 } catch (Exception e) { 119 e.printStackTrace(); 120 } 121 return result; 122 } 123 }
【7】获取验证码类
1 package com.miaodi.getcode; 2 3 import com.alibaba.fastjson.JSONObject; 4 import com.miaodi.comment.Config; 5 import com.miaodi.comment.HttpUtil; 6 7 import java.net.URLEncoder; 8 9 /** 10 * @author: 张瑛 11 * @date: 2019/7/5-12:22 12 */ 13 public class GetMessageCode { 14 15 private static String accountSid = Config.ACCOUNT_SID; 16 private static String rod=smsCode(); //生成一个随机验证码 17 private static String smsContent = "【南京车纷享汽车服务有限公司】登录验证码:"+rod +",如非本人操作,请忽略此短信"; 18 19 //创建验证码 20 public static String smsCode(){ 21 String random=(int)((Math.random()*9+1)*100000)+""; 22 return random; 23 } 24 25 //根据相应的手机号发送验证码 26 public static String getCode(String phone){ 27 String tmpSmsContent = null; 28 try{ 29 tmpSmsContent = URLEncoder.encode(smsContent, "UTF-8"); 30 }catch(Exception e){ 31 e.getMessage(); 32 } 33 34 String url = Config.BASE_URL; 35 String body = "accountSid=" + accountSid + "&to=" + phone + "&smsContent=" + tmpSmsContent 36 + HttpUtil.createCommonParam(Config.ACCOUNT_SID,Config.AUTH_TOKEN); 37 38 // 提交请求 39 String result = HttpUtil.post(url, body); 40 41 42 //字符串转json对象 43 JSONObject jsonObject = JSONObject.parseObject(result); 44 String respCode = jsonObject.getString("respCode"); 45 46 System.out.println("验证码:"+rod); 47 System.out.println("结果码:"+respCode); 48 49 //反馈-00000状态码标识请求成功, 50 String defaultRespCode="0000"; 51 if(defaultRespCode.equals(respCode)){ 52 return rod; 53 }else{ 54 return defaultRespCode; 55 } 56 } 57 58 }
【8】servlet类
1 package com.tencent.loginservlet; 2 3 import com.miaodi.getcode.GetMessageCode; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.annotation.WebServlet; 7 import javax.servlet.http.HttpServlet; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 import java.io.IOException; 11 12 /** 13 * @author: 张瑛 14 * @date: 2019/7/5-10:37 15 */ 16 @WebServlet(name = "LoginServlet",urlPatterns = "/sendSMS") 17 public class LoginServlet extends HttpServlet { 18 19 /** serialVersionUID*/ 20 private static final long serialVersionUID = 1L; 21 22 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 23 request.setCharacterEncoding("utf-8"); 24 String phone=request.getParameter("phone"); 25 //根据获取到的手机号发送验证码 26 String code = GetMessageCode.getCode(phone); 27 System.out.println("返回code"+code); 28 response.getWriter().print(code); 29 30 } 31 32 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 33 this.doPost(request,response); 34 } 35 36 }
【9】login.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 <html> 7 <head> 8 <base href="<%=basePath%>"> 9 <title>测试短信登陆</title> 10 </head> 11 <meta http-equiv="pragma" content="no-cache"> 12 <meta http-equiv="cache-control" content="no-cache"> 13 <meta http-equiv="expires" content="0"> 14 15 <link rel="stylesheet" href="CSS/bootstrap/bootstrap.min.css" /> 16 <script type="text/javascript" src="js/jQuery/jquery-3.4.1.js"></script> 17 <style type="text/css"> 18 #login { 19 width: 450px; 20 height: 100px; 21 margin: 126px auto; 22 } 23 24 #btn { 25 margin-left: 100px; 26 margin-top: -25px; 27 width: 120px; 28 height: 25px; 29 font-size: 11px; 30 } 31 32 body { 33 background-color: #ecfcf9; 34 } 35 </style> 36 </head> 37 <script type="text/javascript"> 38 var InterValObj; //timer变量,控制时间 39 var count = 60; //间隔函数,1秒执行 40 var curCount;//当前剩余秒数 41 42 function sendMessage() { 43 curCount = count; 44 $("#btn").attr("disabled", "true"); 45 $("#btn").val(curCount + "秒后可重新发送"); 46 InterValObj = window.setInterval(SetRemainTime, 1000); //启动计时器,1秒执行一次请求后台发送验证码 TODO 47 } 48 //timer处理函数 49 function SetRemainTime() { 50 if (curCount == 0) { 51 window.clearInterval(InterValObj);//停止计时器 52 $("#btn").removeAttr("disabled");//启用按钮 53 $("#btn").val("重新发送验证码"); 54 } else { 55 curCount--; 56 $("#btn").val(curCount + "秒后可重新发送"); 57 } 58 } 59 </script> 60 61 <body> 62 <div class="container"> 63 <div id="login"> 64 <fieldset> 65 <div id="legend" class=""> 66 <legend class="">用户登录</legend> 67 </div> 68 <form class="form-horizontal" role="form"> 69 70 <div class="form-group"> <label class="col-sm-2 control-label">手机号</label> 71 <div class="col-sm-5"> 72 <input type="text" class="form-control" id="phone" name="phone" placeholder="请输入您的手机号" required> 73 </div> 74 </div> 75 76 <div class="form-group"> <label class="col-sm-2 control-label">验证码</label> 77 <div class="col-sm-3"> 78 <input type="code" class="form-control" id="code" name="code" placeholder="验证码" required> 79 <input class="btn btn-default" id="btn" name="btn" value="发送验证码" /> 80 </div> 81 </div> 82 83 <div class="form-group"> 84 <div class="col-sm-offset-2 col-sm-10"> 85 <button type="button" class="btn btn-success" id="lo">手机号登录</button> 86 </div> 87 </div> 88 89 </form> 90 </fieldset> 91 </div> 92 </div> 93 </body> 94 95 <script type="text/javascript"> 96 var sms = ""; 97 $("#btn").click(function() { 98 var phone = $("#phone").val(); 99 if (phone != "") { 100 sendMessage(); 101 $.ajax({ 102 url : "sendSMS", //发送请求 103 type : "post", 104 data : { 105 "phone" : phone 106 }, 107 success : function(result) { 108 sms = result; 109 } 110 }); 111 } else { 112 alert("请输入手机号"); 113 return false; 114 } 115 }); 116 $("#lo").click(function() { 117 var code = $("#code").val(); 118 if (code == "") { 119 alert("请输入验证码"); 120 } else { 121 if (sms == code) { 122 window.location.href = "success.jsp"; 123 } else { 124 alert("验证码错误"); 125 } 126 ; 127 } 128 ; 129 }); 130 </script> 131 132 </html>
【10】备注:
lib是一些jar包,jar可以从秒嘀云平台的demo中导入到自己的工程中,也可以自己从网上下载,主要用到的是commons-codec-1.9.jar 做加密用的,fastjson-1.2.49.jar 是作json转化用的,其他的没啥用。
页面中引入的bootstrap 和jQuery 库 自己可以从网上下载。succee.jsp 等可以自定义。
实在需要源码的:发邮件到 1953211318@qq.com 看见了就回,看不见就算了。
附上效果链接:http://106.12.207.20/SendSMS2_war/login.jsp
来源:https://www.cnblogs.com/zy-sai/p/11138319.html