一、首先需要去阿里云注册账号并登录
二、注册阿里云的短信服务 会有100条免费短信 获取自己的AccessKey(accessKeyId,accessKeySecret)
三、在阿里云短信服务 注册短信的 签名 和 模板
阿里云短信服务参考地址:https://www.aliyun.com/ss/?k=%E7%9F%AD%E4%BF%A1%E6%9C%8D%E5%8A%A1&accounttraceid=b95a6b72bbdb45f6942490006a7dd4ebvvkl
maven
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.0.8</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>1.1.0</version></dependency>
以下为实现的代码demo 框架为SSM
NoteController
package com.yannis.controller;import com.alibaba.fastjson.support.spring.FastJsonJsonView; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest; import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; import com.google.gson.internal.bind.JsonAdapterAnnotationTypeAdapterFactory; import com.yannis.json.AjaxJson; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.Timer; import java.util.TimerTask; import java.util.regex.Matcher; import java.util.regex.Pattern;/*** @Author: ysw* @Date: 2020/9/7 10:59*/ @Controller @RequestMapping("/note") public class NoteController {//产品名称:云通信短信API产品,开发者无需替换static final String product = "Dysmsapi";//产品域名,开发者无需替换static final String domain = "dysmsapi.aliyuncs.com";// TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)static final String accessKeyId = "";static final String accessKeySecret = "";@RequestMapping("adduser")public String adduser(HttpServletRequest request,HttpServletResponse response){request.setAttribute("view","1");return "/adduser";}@RequestMapping("/sendNote")@ResponseBodypublic AjaxJson sendNote(String phone, HttpServletRequest res, HttpServletResponse req){AjaxJson j =new AjaxJson();LinkedHashMap<String,Object> hashMap = new LinkedHashMap<>();//发短信try {SendSmsResponse response = sendSms(phone,"","");System.out.println("短信接口返回的数据----------------");System.out.println("Code=" + response.getCode());System.out.println("Message=" + response.getMessage());System.out.println("RequestId=" + response.getRequestId());System.out.println("BizId=" + response.getBizId());Thread.sleep(3000L);if(response.getCode() != null && response.getCode().equals("OK")) {QuerySendDetailsResponse querySendDetailsResponse = querySendDetails(response.getBizId(),phone);System.out.println("短信明细查询接口返回数据----------------");System.out.println("Code=" + querySendDetailsResponse.getCode());System.out.println("Message=" + querySendDetailsResponse.getMessage());int i = 0;String content="";for(QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO : querySendDetailsResponse.getSmsSendDetailDTOs()) {System.out.println("SmsSendDetailDTO["+i+"]:");content = smsSendDetailDTO.getContent();System.out.println("Content=" + content);System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode());System.out.println("OutId=" + smsSendDetailDTO.getOutId());System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum());System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate());System.out.println("SendDate=" + smsSendDetailDTO.getSendDate());System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus());System.out.println("Template=" + smsSendDetailDTO.getTemplateCode());}System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount());System.out.println("RequestId=" + querySendDetailsResponse.getRequestId());String yzmFromSms = getYzmFromSms(content);HttpSession session = res.getSession();session.setAttribute("code",yzmFromSms);session.setAttribute("phone",phone);session.setAttribute("msg","验证码发送成功");//定时5分钟删除验证码removeAttrbute(session, "code");removeAttrbute(session, "phone");removeAttrbute(session, "msg");j.setSuccess(true);}} catch (ClientException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}return j;}/*** phone 手机号* singName 申请的签名* templateCode 模板code* *///发送短信public static SendSmsResponse sendSms(String phone,String singName,String templateCode) throws ClientException {//可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");//初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);//组装请求对象-具体描述见控制台-文档部分内容SendSmsRequest request = new SendSmsRequest();//必填:待发送手机号request.setPhoneNumbers(phone); //必填:短信签名-可在短信控制台中找到request.setSignName(singName); //必填:短信模板-可在短信控制台中找到request.setTemplateCode(templateCode); //可选:模板中的变量替换JSON串,如模板内容为"${code}"时,此处的值为request.setTemplateParam("{'code': '"+randomSix()+"'}");//选填-上行短信扩展码(无特殊需求用户请忽略此字段)//request.setSmsUpExtendCode("验证码");//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者request.setOutId("yourOutId");//hint 此处可能会抛出异常,注意catchSendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);return sendSmsResponse;}//查询发送短信的信息public static QuerySendDetailsResponse querySendDetails(String bizId,String phone) throws ClientException {//可自助调整超时时间System.setProperty("sun.net.client.defaultConnectTimeout", "10000");System.setProperty("sun.net.client.defaultReadTimeout", "10000");//初始化acsClient,暂不支持region化IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);IAcsClient acsClient = new DefaultAcsClient(profile);//组装请求对象QuerySendDetailsRequest request = new QuerySendDetailsRequest();//必填-号码request.setPhoneNumber(phone);//可选-流水号request.setBizId(bizId);//必填-发送日期 支持30天内记录查询,格式yyyyMMddSimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");request.setSendDate(ft.format(new Date()));//必填-页大小request.setPageSize(10L);//必填-当前页码从1开始计数request.setCurrentPage(1L);//hint 此处可能会抛出异常,注意catchQuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);return querySendDetailsResponse;}//生成6位验证码public static int randomSix(){//随机生成六位随机数StringBuffer stringBuffer=new StringBuffer();for (int x=0;x<=5;x++) {int random = (int) (Math.random() * (10 - 1));stringBuffer.append(random);}String string = stringBuffer.toString();System.out.println("生成的六位验证码 :"+Integer.parseInt(string));return Integer.parseInt(string);}//提取6位验证码private String getYzmFromSms(String smsBody) {Pattern pattern = Pattern.compile("\\d{6}");Matcher matcher = pattern.matcher(smsBody);if (matcher.find()) {return matcher.group();}return null;}/*** 设置5分钟后删除session中的验证码* @param session* @param attrName*/private void removeAttrbute(final HttpSession session, final String attrName) {final Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {// 删除session中存的验证码session.removeAttribute(attrName);timer.cancel();}}, 5 * 60 * 1000);}}
adduser.jsp 登录页面 jquery 换成自己的路径
<%@ page language="java" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <head> <title>手机号登录</title><style type="text/css"> .main {/*设置外边距,下面有30px距离*/margin: 0px 0px 30px 0px;/*背景色*/background-color: #ffffff;/*字体大小*/font-size: 12px;/*文字颜色*/color: #000000;/*文本对齐方式*/text-align: center;/*垂直对齐方式*/vertical-align: top;/*设置行高*/line-height: 150%;font-family: Arial, Helvetica, sans-serif; } /*设置a标签 字体12px 颜色 #0066FF*/ a {font-size: 12px;color: #0066FF; /*#1E33F7*/ } /*设置未访问的超连接无下划线*/ a:link {text-decoration: none; } /*设置访问后的连接颜色为#0066ff 也无下划线*/ a:visited {text-decoration: none;color: #0066FF; } /*设置鼠标移到超连接上无下划线颜色为#990099*/ a:hover {text-decoration: none;color: #990099; /*颜色变换*/ } /*设置选定的超连接无下划线,颜色为#0066ff*/ a:active {text-decoration: none;color: #0066FF; }/*设置所有td标签*/ td {text-align: left;vertical-align: top;font-size: 12px; } /*设置所有的hr标签*/ hr {/*颜色*/color: #cccccc;/*高度*/height: 1px;/*上外边距5px*/margin-top: 5px;/*下外边距5px*/margin-bottom: 5px;/*分隔线如果超出框架部分隐藏*/overflow: hidden; } /*设置h1*/ h1 {font-size: 14px;color: #000000;margin-bottom: 5px;font-weight: bold;display: inline;text-align: center; }#head {/*设置head这个div宽度为100%*/width: 100%; }.headtab {width: 100%; }.headta td {/*设置td内边距上10px 右50px 下25px 左135px*/padding: 10px 50px 25px 135px; }#menu {width: 100%;background-color: #1c3f09; /*设置背景色*/border-top-width: 4px; /*设置上边框宽度4px*/border-top-style: solid; /*设置上边框样式 实线*/border-top-color: #82b211; /*设置上边框的颜色 #82b211*/text-align: center;font-size: 14px;padding: 10px 0px 10px 0px; }#menu td {text-align: center; }#menu a {font-size: 14px;color: #ffffff; /*超连接文字颜色*/font-weight: bold; /*超连接字体加粗*/padding: 10px 10px 10px 10px; /*超连接内边距*/ }#menu a:link {text-decoration: none;font-weight: bold; }#menu a:visited {text-decoration: none;color: #FFFFFF;font-weight: bold; }#menu a:hover {text-decoration: none;color: #999999; /*颜色变换*/font-weight: bold; }#menu a:active {text-decoration: none;color: #FFFFFF;font-weight: bold; }#search {width: 100%;text-align: center;color: #ffffff;font-weight: bold;padding: 5px 0px 5px 0px;background-color: #b6b684; }.inputtxt {width: 130px;height: 18px;border: 1px solid #999999; } /*注册页面content部分整体设计*/ #content {width: 900px;background-color: #fcfdef;border: 1px solid #eeeddb;margin-right: auto;margin-left: auto; } /*设置边框*/ .upline {border-bottom-width: 1px;border-bottom-style: dashed;border-bottom-color: #b0bec7;padding-top: 5px;padding-bottom: 5px;margin: 20px; } /*设置文本框样式*/ .txtinput {margin-left: 20px;font-size: 15px;width: 200px;height: 25px;border: 1px solid #a4b4bd; } /*设置文本域样式*/ .txtarea {margin-left: 20px;font-size: 15px;width: 350px;height: 75px;border: 1px solid #a4b4bd; }#foot {width: 100%;background-color: #efeedc;margin-top: 15px; } </style><script src="../js/jquery.min.js"></script></head> <body class="main"><div id="content"><form id="myForm" method="post" onsubmit="return reg(this);"><table width="850px" border="0" cellspacing="4"><tr><td style="padding: 30px"><h1>手机号登录</h1><table width="100%" border="0" cellspacing="2" class="upline"><tr><td width="30%" style="text-align: right;"><font size="2px">手机号</font></td><td width="30%"><input type="text" name="phone" id ="phone" class="txtinput" value="${phone}"> </td><td width="40%"><font color="#999999">* 请填写您的手机号 <span id="tise"></span></font></td> </tr><tr><td style="text-align: right;"><font size="2px">验证码</font></td><td><input type="text" name="code" class="txtinput" id="code" placeholder="请输短信验证码"/></td><td><input id="btn" type="button" onclick="noteTime(this)" value="免费获取验证码"><span id ="error_msg">${msg}</span></td></tr> <%--<tr>--%><%--<td style="text-align: right;"><font size="2px">密码</font></td>--%><%--<td><input type="password" name="password" class="txtinput" id="password" onchange="checkpwd()"/></td>--%><%--<td><font color="#999999">* 密码必须6-18位</font></td>--%><%--</tr>--%><%--<tr>--%><%--<td style="text-align: right;"><font size="2px">重复密码</font></td>--%><%--<td><input type="password" name="repassword"--%><%--class="txtinput"></td>--%><%--<td><font color="#999999">* 两次密码需要一致</font></td>--%><%--<td> </td>--%><%--</tr> --%><%----%></table><table width="100%" border="0" cellspacing="4"><tr><td width="51%" style="text-align:right"><input id="sub" type="button" value="确定"><FONT face="宋体"> </FONT><td width="49%" > <INPUT type="button" onclick="history.go(-1)" value="返回" /> <spanid="Label1"> </span></td></tr> </table></form></div><script>$(function () {var view = "${view}";if (view == "1"){var obj = $("#btn");settime(obj);}});function reg(form) {if (form.phone.value == "") {alert("用户不能为空!");return false;} else if (form.password.value == "") {alert("密码不能为空!");return false;} else if (form.repassword.value == "") {alert("确认密码不能为空!");return false;}else if (form.code.value == "") {alert("验证码不能为空!");return false;} else if (form.repassword.value != form.password.value ) {alert("两次密码不相同!");return false;} else if(!checkpwd()){return false;} else if(!confirm('注册信息确认提交?')){return false;}}//验证密码位数function checkpwd() {var check;var reg = /[^A-Za-z0-9_]+/;var regs = /^[a-zA-Z0-9_\u4e00-\u9fa5] + $ /;var password = document.getElementById("password").value;if (password.length < 6 || password.length > 18 || regs.test(password)) {alert("密码输入不合法,请重新输入!");document.getElementById("password").focus();check = false;} else {check = true;}return check;}</script><script>//定时60秒重新发送var countdown=60;function noteTime(){var phone = $("#phone").val();if (phone!=""){$.ajax({type:'post',url:"${pageContext.request.contextPath}/note/sendNote?phone="+phone,dataType: "json",success: function(data){window.location.href = "${pageContext.request.contextPath}/note/adduser";}});}else{alert("请输入手机号");}}function settime(obj) { //发送验证码倒计时if (countdown == 0) {obj.attr('disabled',false);obj.val("免费获取验证码");countdown = 60;return;} else {obj.attr('disabled',true);obj.val("重新发送(" + countdown + ")");countdown--;}//定时setTimeout(function() {settime(obj)},1000);}</script><script>$("#sub").click(function () {var code = "${code}";var codes = $("#code").val();if (codes != ""){if (code == codes){alert("验证成功");alert(code+" " +codes);window.location.href = "../index.jsp";}else{alert("验证失败");}} else{alert("请输入验证码");}<%--$.ajax({--%><%--type:'post',--%><%--url:"${pageContext.request.contextPath}/note/selectNote"--%><%--});--%>//$("#myForm").submit();}); </script> </body> </html>
index.jsp 模拟成功页面
<%@ page language="java" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <html> <body> <h2>手机登录成功</h2></body> </html>
程序页面