首页 > 编程知识 正文

为什么验证码发不过来,手机怎么收不到短信验证码

时间:2023-05-06 00:14:32 阅读:139297 作者:688

通过工具类发送信息,定制信息类的内容

1 .引入依赖

ependencygroupidcom.github.qcloudsms/groupidartifactidqcloudsms/artifactidversionrelease/versionscopecompile/scopi le ependencydependencygroupidcom.q cloud/groupidartifactidcos _ API/artifactidversionrelease/versionscopecompecompile/scopeexclusionsexclusiongroupidorg.slf4j/groupidartifactidslf4j-log4j 12/artifact id/exclusion/exclusions/dependendend

package utils; import bean.config.QCloud; import com.github.qcloudsms.smsmultisender; import com.github.qcloudsms.smsmultisenderresult; import com.github.qcloudsms.smssinglesender; import com.github.qcloudsms.smssinglesenderresult; import com.github.qcloudsms.http client.http exception; import org.json.JSONException; import javax.annotation.resource; import java.io.IOException; publicclasssmsverification { qcloudqcloud=newq cloud (; /***SMS验证码工具类单次发送* @param randomNum生成的随机数* @param min验证码时效* @param phoneNumbers需要发送SMS的移动电话号码String[]可多次发送* @ retom publicbooleansinglesender (string random num,String min,String phoneNumbers ) system.out.println ) qcloud.getappid ) try { String[] params={randomNum,min}; //数组的具体元素数量和模板中的变量数量必须一致。 例如,在案例中,templateId:5678对应于变量。 参数数组中的元素数量也必须是smssinglesendersender=newsmssinglesender (q cloud.get appid ) )的sssinglesenderresultresult=s sender 如果未指定qCloud.getTemplateId )、params、'武汉威尔'、//签名参数或为空,则消息system.out.println(result )将使用默认签名}catch(httpexceptione ) { //HTTP响应代码错误e.printStackTrace ); }catch(JSONexceptione ) { //json分析错误e.printStackTrace ); }catch(IOexceptione ) /网络io错误e.printStackTrace ); }

return true; } /** * 短信验证码工具类 批量发送 * @param randomNum 随机数 * @param min 时效时间 * @param phoneNumbers 号码数组 * @return 是否成功 */ public Boolean SmsMultiSender (String randomNum,String min,String[] phoneNumbers){ try { String[] params = {randomNum,min};//数组具体的元素个数和模板中变量个数必须一致,例如事例中templateId:5678对应一个变量,参数数组中元素个数也必须是一个 SmsMultiSender msender = new SmsMultiSender(qCloud.getAppid(), qCloud.getAppkey()); SmsMultiSenderResult result = msender.sendWithParam("86", phoneNumbers, qCloud.getTemplateId(), params, "某公司", "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信 System.out.println(result); } catch (HTTPException e) { // HTTP响应码错误 e.printStackTrace(); } catch (JSONException e) { // json解析错误 e.printStackTrace(); } catch (IOException e) { // 网络IO错误 e.printStackTrace(); } return true; }}

这里有两个方法,一个是单条发送给单个手机用户,一个是多条发送给多个手机用户(类似于群发)

再就是对发送的验证码进行存储(因为之后要对其验证)
常用的方法是存放到redis,或者java缓存(cache)
如果用户并发量比较大的话就用redis,用户并发量小的话直接用cache,也比较简单
我用的是cache

package com.vshare.research.api.utils;import java.util.HashMap;import java.util.Map;import java.util.concurrent.*;public class Cache { //键值对集合 private final static Map<String, Entity> map = new HashMap<>(); //定时器线程池,用于清除过期缓存 private final static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); /** * 添加缓存 * * @param key 键 * @param data 值 */ public synchronized static void put(String key, Object data) { Cache.put(key, data, 0); } /** * 添加缓存 * * @param key 键 * @param data 值 * @param expire 过期时间,单位:毫秒, 0表示无限长 */ public synchronized static void put(String key, Object data, long expire) { //清除原键值对 Cache.remove(key); //设置过期时间 if (expire > 0) { Future future = executor.schedule(new Runnable() { @Override public void run() { //过期后清除该键值对 synchronized (Cache.class) { map.remove(key); } } }, expire, TimeUnit.MILLISECONDS); map.put(key, new Entity(data, future)); } else { //不设置过期时间 map.put(key, new Entity(data, null)); } } /** * 读取缓存 * * @param key 键 * @return */ public synchronized static Object get(String key) { Entity entity = map.get(key); return entity == null ? null : entity.getValue(); } /** * 读取缓存 * * @param key 键 * * @param clazz 值类型 * @return */ public synchronized static <T> T get(String key, Class<T> clazz) { return clazz.cast(Cache.get(key)); } /** * 清除缓存 * * @param key * @return */ public synchronized static Object remove(String key) { //清除原缓存数据 Entity entity = map.remove(key); if (entity == null) return null; //清除原键值对定时器 Future future = entity.getFuture(); if (future != null) future.cancel(true); return entity.getValue(); } /** * 查询当前缓存的键值对数量 * * @return */ public synchronized static int size() { return map.size(); } /** * 缓存实体类 */ private static class Entity { //键值对的value private Object value; //定时器Future private Future future; public Entity(Object value, Future future) { this.value = value; this.future = future; } /** * 获取值 * * @return */ public Object getValue() { return value; } /** * 获取Future对象 * * @return */ public Future getFuture() { return future; } }}

本工具类主要采用HashMap+定时器线程池实现,map用于存储键值对数据,map的value是Cache的内部类对象Entity,Entity包含value和该键值对的生命周期定时器Future。Cache类对外只提供了put(key, value), put(key, value, expire), get(key), get(key, class), remove(key), size()几个同步方法。
当添加键值对数据的时候,首先会调用remove()方法,清除掉原来相同key的数据,并取消对应的定时清除任务,然后添加新数据到map中,并且,如果设置了有效时间,则添加对应的定时清除任务到定时器线程池。

发送验证码,前台传手机号过来,然后调用之前写好的工具类,这里生成一个6位的随机数作为验证码,有效时长直接写成String,比如说String=“1”,这就代表1分钟,但是cache缓存也要定义有效时长,时间过了会自动清楚缓存,但是注意,这里的时间单位是毫秒

@Resource SMSVerification smsVerification; /** * @param mobile 手机号 * @return 是否发送成功 * @Description 发送验证码 */ @GetMapping("getVerificationCode") public boolean getVerificationCode(String mobile) { int random = (int) ((Math.random() * 9 + 1) * 100000); String randomNum = String.valueOf(random); String min = "2"; Cache.put(mobile, randomNum, 120000); return smsVerification.SingleSender(randomNum, min, mobile); }

接下来就是从cache中取出验证码,cache中是以键值对的形式存储的,所以建议直接以手机号作为key,验证码作为value

/** * @param mobile 手机号 * @param code 验证码 * @return * @Description 验证验证码 */ @PostMapping("verifyCode") public String verifyCode(String mobile, String code) { String randomNum = (String) Cache.get(mobile); if (randomNum != null && randomNum.equals(code)) { UserInfo userInfo = iUserInfoService.selectOne(Condition.create().eq("mobile", mobile)); if (userInfo != null) { return "此号码已被绑定"; } else { UserInfo userInfo1 = new UserInfo(); userInfo1.setMobile(mobile); iUserInfoService.insert(userInfo1); return "绑定成功"; } } else { return "验证码错误"; } }

一般来说手机号绑定之后,要进行一些相关操作,比如需要在用户表里添加一条用户信息

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。