• 技术文章 >Java >Java入门

    java实现发送验证码短信功能

    VV2021-01-20 09:52:53转载840

    功能需求:

    (学习视频分享: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入门教程

    以上就是java实现发送验证码短信功能的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:csdn,如有侵犯,请联系admin@php.cn删除
    专题推荐:java 验证码 短信
    上一篇:char类型占几个字节 下一篇:javadoc规范介绍
    大前端线上培训班

    相关文章推荐

    • php如何实现验证码看不清换一张的效果• php验证码图片不显示图片怎么办• php怎么解决验证码无法显示的问题• php 验证码乱码怎么办

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网