功能需求:
(学习视频分享:java视频教程)
1、后台随机产生4个字符
2、1分钟以内只能发送1次验证码
3、超过1分钟,但在5分钟以内,发送的验证码依然是第一次产生的验证码字符
4、超过了5分钟以后,产生全新的验证码
前端使用什么框架先不管
依赖配置
短信依赖包 redis配置,因为验证码和手机号存储在redis中
短信平台使用的建网 sms ,http://www.smschinese.cn/ 可以免费使用5条 测试即可
注意:配置接口的 账户名 和 密钥 每个人是不同的,复制过去记得更改
短信依赖包
<!--短信jar包--> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency>
redis jar包
<!--redis jar 包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
使用redis前,要先配置连接,在application.properties配置
# redis 属性信息 ## redis数据库索引(默认为0) spring.redis.database=0 ## redis服务器地址 spring.redis.host=localhost ## redis服务器连接端口 spring.redis.port=6379 ## redis服务器连接密码(默认为空) ## spring.redis.password=123456 ## 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=8 ## 连接池中的最大空闲连接 spring.redis.jedis.pool.max-idle=8 ## 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedis.pool.max-wait=-1ms ## 连接池中的最小空闲连接 spring.redis.jedis.pool.min-idle=0
创建一个工具类 StrUtils.getComplexRandomString ()// 获取随机字符 位数自己输入
import java.util.ArrayList; import java.util.List; import java.util.Random; /** * @author yaohuaipeng * @date 2018/10/26-16:16 */ public class StrUtils { /** * 把逗号分隔的字符串转换字符串数组 * * @param str * @return */ public static String[] splitStr2StrArr(String str,String split) { if (str != null && !str.equals("")) { return str.split(split); } return null; } /** * 把逗号分隔字符串转换List的Long * * @param str * @return */ public static List<Long> splitStr2LongArr(String str) { String[] strings = splitStr2StrArr(str,","); if (strings == null) return null; List<Long> result = new ArrayList<>(); for (String string : strings) { result.add(Long.parseLong(string)); } return result; } /** * 把逗号分隔字符串转换List的Long * * @param str * @return */ public static List<Long> splitStr2LongArr(String str,String split) { String[] strings = splitStr2StrArr(str,split); if (strings == null) return null; List<Long> result = new ArrayList<>(); for (String string : strings) { result.add(Long.parseLong(string)); } return result; } public static String getRandomString(int length) { String str = "0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(10); sb.append(str.charAt(number)); } return sb.toString(); } public static String getComplexRandomString(int length) { String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(62); sb.append(str.charAt(number)); } return sb.toString(); } public static String convertPropertiesToHtml(String properties){ //1:容量:6:32GB_4:样式:12:塑料壳 StringBuilder sBuilder = new StringBuilder(); String[] propArr = properties.split("_"); for (String props : propArr) { String[] valueArr = props.split(":"); sBuilder.append(valueArr[1]).append(":").append(valueArr[3]).append("<br>"); } return sBuilder.toString(); } }
创建短信发送类 配置接口,其它类调用这个类的send方法传入手机号和发送内容即可
import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.PostMethod; import java.io.IOException; public class SendMsgUtils { private static final String UID = "amazingwest";//这是建网SMS 上的登陆账号 private static final String KEY = "d41d8cd98f00b204e980"; //这是密钥 /** * 手机发送短信 * @param phone 手机号码 * @param context 发送短信内容 */ public static void send(String phone, String context) { PostMethod post = null; try { //创建Http客户端 HttpClient client = new HttpClient(); //创建一个post方法 post = new PostMethod("http://utf8.api.smschinese.cn"); //添加请求头信息 post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf8");//在头文件中设置转码 NameValuePair[] data = {new NameValuePair("Uid", UID), new NameValuePair("Key", KEY), new NameValuePair("smsMob", phone), new NameValuePair("smsText", context)}; //设置请求体 post.setRequestBody(data); //执行post方法 client.executeMethod(post); //获取响应头信息 Header[] headers = post.getResponseHeaders(); //获取状态码 int statusCode = post.getStatusCode(); System.out.println("statusCode:" + statusCode); //循环打印头信息 for (Header h : headers) { System.out.println(h.toString()); } //获取相应体 String result = new String(post.getResponseBodyAsString().getBytes("utf8")); System.out.println(result); //打印返回消息状态 } catch (IOException e) { e.printStackTrace(); } finally { if (post != null) { //关闭资源 post.releaseConnection(); } } } }
创建注册常量类,主要用来区分验证码是用来注册还是登陆或者找回密码
/** * 验证码常量 */ public class VerificationConstant { //用户注册常量 public static final String USER_REG = "user_reg"; }
前台点击发送验证码 首先要考虑多个用户同时注册,key值不能写死
首先根据手机号加注册标识(KEY)判断redis中值value是否存在,不存在就创建一个键,key为手机号+加注册标识,
判断时间,就是创建redis键值对的时候就,value会加上一个当前时间戳,取value第一次创建的时间会分割value 拿当前时间戳减去第一次创建的时间戳就能得出具体的时间
第一次创建键值 设置键的存活时间为5分钟 300秒
发送验证码短信,前端传来手机号码,在这里进行业务逻辑判断 不需要判断手机号是否注册,这是其它类的事情 使用redisTemplate 就必须得 引入redis jar包
StrUtils.getComplexRandomString(4) 这就是上面创建的工具类中的一个方法,创建4位字符的随机数,
StringUtils.isEmpty 是 import org.springframework.util.StringUtils 别弄错了
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.concurrent.TimeUnit; @Service public class VerificationCodeServiceImpl implements IVerificationCodeService { @Autowired private RedisTemplate redisTemplate; /** * 发送注册验证码 * 验证码需求: * 1.后台随机产生4个字符 * 2.1分钟以内只能发送1次验证码 * 3.超过1分钟,但在5分钟以内,发送的验证码依然是第一次产生的验证码字符 * 4.超过了5分钟以后,产生全新的验证码 * @return */ @Override public void sendRegisterVerificationCode(String phone) throws CustomException { //随机产生4个字符 String value = StrUtils.getComplexRandomString(4); //在redis中通过key获取对应的值 value:时间戳 String valueCode = (String) redisTemplate.opsForValue().get(phone + ":" + VerificationConstant.USER_REG); //如果不为空,就意味着验证码没有过期,依然是在5分钟以内 if(!StringUtils.isEmpty(valueCode)){ //开始时间戳 String beginTimer = valueCode.split(":")[1]; if(System.currentTimeMillis()-Long.valueOf(beginTimer)<=60*1000){ //自定义异常,自己创建一个就可以了 throw new CustomException("亲!一分钟以内不能发送多次验证码!!"); } //证明是超过了1分钟,但依然在5分钟以内,还是用之前的验证码 value = valueCode.split(":")[0]; } //存储redis中,设置有效期是5分钟 k=phone:USER_REG v= value:时间戳 // RedisUtil.set(phone:USER_REG, value:System.currentTimeMillis(), 5MIN); redisTemplate.opsForValue().set(phone + ":" + VerificationConstant.USER_REG, value + ":" + System.currentTimeMillis(), 5, TimeUnit.MINUTES); //发送手机验证码 String context = "尊敬的用户,您的验证码为:" + value + ",请您在5分钟以内完成注册!!"; //发送短信 // SendMsgUtils.send(phone, context); System.out.println(context); } }
完成。
相关推荐:java入门教程
Atas ialah kandungan terperinci java实现发送验证码短信功能. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!