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
